static int tdav_consumer_audiounit_stop(tmedia_consumer_t* self)
{
	tdav_consumer_audiounit_t* consumer = (tdav_consumer_audiounit_t*)self;
	
    if(!consumer){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}
	if(!consumer->started){
		TSK_DEBUG_INFO("Not started");
		return 0;
	}
	else {
		int ret = tdav_audiounit_handle_stop(consumer->audioUnitHandle);
		if(ret){
			TSK_DEBUG_ERROR("tdav_audiounit_handle_stop failed with error code=%d", ret);
			return ret;
		}
	}
#if TARGET_OS_IPHONE
	//https://devforums.apple.com/thread/118595
	if(consumer->audioUnitHandle){
		tdav_audiounit_handle_destroy(&consumer->audioUnitHandle);
	}
#endif
	
	consumer->started = tsk_false;
	TSK_DEBUG_INFO("AudioUnit consumer stoppped");
	return 0;	
	
}
static int tdav_speex_jitterbuffer_open(tmedia_jitterbuffer_t* self, uint32_t frame_duration, uint32_t rate, uint32_t channels)
{
	tdav_speex_jitterbuffer_t *jitterbuffer = (tdav_speex_jitterbuffer_t *)self;
	spx_int32_t tmp;

	TSK_DEBUG_INFO("Open speex jb (ptime=%u, rate=%u)", frame_duration, rate);

	if(!(jitterbuffer->state = jitter_buffer_init((int)frame_duration))){
		TSK_DEBUG_ERROR("jitter_buffer_init() failed");
		return -2;
	}
	jitterbuffer->rate = rate;
	jitterbuffer->frame_duration = frame_duration;
	jitterbuffer->channels = channels;
	jitterbuffer->x_data_size = ((frame_duration * jitterbuffer->rate) / 500) << (channels == 2 ? 1 : 0);

	jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_GET_MARGIN, &tmp);
	TSK_DEBUG_INFO("Default Jitter buffer margin=%d", tmp);
	jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_GET_MAX_LATE_RATE, &tmp);
	TSK_DEBUG_INFO("Default Jitter max late rate=%d", tmp);
	
	if((tmp = tmedia_defaults_get_jb_margin()) >= 0){
		jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_SET_MARGIN, &tmp);
		TSK_DEBUG_INFO("New Jitter buffer margin=%d", tmp);
	}
	if((tmp = tmedia_defaults_get_jb_max_late_rate()) >= 0){
		jitter_buffer_ctl(jitterbuffer->state, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp);
		TSK_DEBUG_INFO("New Jitter buffer max late rate=%d", tmp);
	}

	return 0;
}
static int tdav_producer_audiounit_stop(tmedia_producer_t* self)
{
    tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)self;
	
    if(!producer){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}
	if(!producer->started){
		TSK_DEBUG_INFO("Not started");
		return 0;
	}
	else {
		int ret = tdav_audiounit_handle_stop(producer->audioUnitHandle);
		if(ret){
			TSK_DEBUG_ERROR("tdav_audiounit_handle_stop failed with error code=%d", ret);
			// do not return even if failed => we MUST stop the thread!
		}
#if TARGET_OS_IPHONE
		//https://devforums.apple.com/thread/118595
		if(producer->audioUnitHandle){
			tdav_audiounit_handle_destroy(&producer->audioUnitHandle);
		}
#endif
	}	
	producer->started = tsk_false;
	TSK_DEBUG_INFO("AudioUnit producer stoppped");
	return 0;	
}
Exemple #4
0
static int tdav_codec_opus_open(tmedia_codec_t* self)
{
    tdav_codec_opus_t* opus = (tdav_codec_opus_t*)self;
    int opus_err;

    if(!opus) {
        TSK_DEBUG_ERROR("Invalid parameter");
        return -1;
    }

    // Initialize the decoder
    if(!opus->decoder.inst) {
        TSK_DEBUG_INFO("[OPUS] Open decoder: rate=%d, channels=%d", (int)self->in.rate, (int)TMEDIA_CODEC_AUDIO(self)->in.channels);
        if(!(opus->decoder.inst = opus_decoder_create((opus_int32)self->in.rate, (int)TMEDIA_CODEC_AUDIO(self)->in.channels, &opus_err)) || opus_err != OPUS_OK) {
            TSK_DEBUG_ERROR("Failed to create Opus decoder(rate=%d, channels=%d) instance with error code=%d.", (int)self->in.rate, (int)TMEDIA_CODEC_AUDIO(self)->in.channels, opus_err);
            return -2;
        }
    }
    opus->decoder.last_seq  = 0;

    // Initialize the encoder
    if(!opus->encoder.inst) {
        TSK_DEBUG_INFO("[OPUS] Open encoder: rate=%d, channels=%d", (int)self->out.rate, (int)TMEDIA_CODEC_AUDIO(self)->out.channels);
        if(!(opus->encoder.inst = opus_encoder_create((opus_int32)self->out.rate, (int)TMEDIA_CODEC_AUDIO(self)->out.channels, OPUS_APPLICATION_VOIP, &opus_err)) || opus_err != OPUS_OK) {
            TSK_DEBUG_ERROR("Failed to create Opus decoder(rate=%d, channels=%d) instance with error code=%d.", (int)self->out.rate, (int)TMEDIA_CODEC_AUDIO(self)->out.channels, opus_err);
            return -2;
        }
    }
#if TDAV_UNDER_MOBILE /* iOS, Android and WP8 */
    opus_encoder_ctl(opus->encoder.inst, OPUS_SET_COMPLEXITY(3));
#endif
    opus_encoder_ctl(opus->encoder.inst, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));

    return 0;
}
static void* TSK_STDCALL __record_thread(void *param)
{
	tdav_producer_waveapi_t* producer = (tdav_producer_waveapi_t*)param;  
	DWORD dwEvent;
	tsk_size_t i;

	TSK_DEBUG_INFO("__record_thread -- START");

	SetPriorityClass(GetCurrentThread(), REALTIME_PRIORITY_CLASS);

	for(;;){
		dwEvent = WaitForMultipleObjects(2, producer->events, FALSE, INFINITE);

		if (dwEvent == 1){
			break;
		}

		else if (dwEvent == 0){
			EnterCriticalSection(&producer->cs);
			for(i = 0; i< sizeof(producer->hWaveHeaders)/sizeof(LPWAVEHDR); i++){
				if(producer->hWaveHeaders[i] && (producer->hWaveHeaders[i]->dwFlags & WHDR_DONE)){
					record_wavehdr(producer, producer->hWaveHeaders[i]);
				}
			}
			LeaveCriticalSection(&producer->cs);
		}
	}

	TSK_DEBUG_INFO("__record_thread() -- STOP");
	

	return tsk_null;
}
Exemple #6
0
int publish_handle_event(const tsip_event_t *_event)
{
	const tsip_publish_event_t* pub_event = TSIP_PUBLISH_EVENT(_event);
	const session_t* session;
	tsip_ssession_id_t sid;

	/* Find associated session */
	sid = tsip_ssession_get_id(_event->ss);
	if(!(session = session_get_by_sid(ctx->sessions, sid))){
		TSK_DEBUG_WARN("Failed to match session event.");
		return -1;
	}

	switch(pub_event->type){
		case tsip_ao_publish: /* Answer to outgoing PUBLISH */
			{
				if(_event->sipmessage){
					if(TSIP_MESSAGE_IS_RESPONSE(_event->sipmessage)){
						TSK_DEBUG_INFO("Event: Answer to outgoing PUBLISH. Code=%d and phrase=%s", 
							_event->sipmessage->line.response.status_code, _event->sipmessage->line.response.reason_phrase);
					}
					else{
						// request
					}
				}
				break;
			}
		
		case tsip_ao_unpublish: /* Answer to outgoing unPUBLISH */
			{
				if(_event->sipmessage){
					if(TSIP_MESSAGE_IS_RESPONSE(_event->sipmessage)){
						TSK_DEBUG_INFO("Event: Answer to outgoing UNPUBLISH. Code=%d and phrase=%s", 
							_event->sipmessage->line.response.status_code, _event->sipmessage->line.response.reason_phrase);
					}
					else{
						// request
					}
				}
				break;
			}

		/* Server events (For whose dev. Server Side IMS Services) */
		case tsip_i_publish: /* Incoming PUBLISH */
		case tsip_i_unpublish: /* Incoming unPUBLISH */
			{	
				TSK_DEBUG_WARN("Event not support by Client Framework.");
				break;
			}

		default:
			{	/* Any other event */
				TSK_DEBUG_WARN("%d not a valid SIP Subscription event.", pub_event->type);
				break;
			}
	}

	return 0;
}
void __CFWriteStreamClientCallBack(CFWriteStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo) {
    // Extract the context
    tnet_transport_t *transport = (tnet_transport_t *) clientCallBackInfo;
	transport_context_t *context = transport->context;
    
    /* lock context */
    tsk_safeobj_lock(context);
    
    // Extract the native socket
    CFDataRef data = CFWriteStreamCopyProperty(stream, kCFStreamPropertySocketNativeHandle);
    CFSocketNativeHandle fd;
    CFDataGetBytes(data, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8*) &fd);
    CFRelease(data);
    transport_socket_t *sock = (transport_socket_t *) getSocket(context, fd);
    
    switch(eventType) {
        case kCFStreamEventOpenCompleted:
        {
            TSK_DEBUG_INFO("__CFWriteStreamClientCallBack --> kCFStreamEventOpenCompleted");
            
            if (TNET_SOCKET_TYPE_IS_SECURE(sock->type)) {
#if !TARGET_OS_IPHONE
                SSLContextRef sslContext = NULL;
                data = CFWriteStreamCopyProperty(stream, kCFStreamPropertySocketSSLContext);
                CFDataGetBytes(data, CFRangeMake(0, sizeof(SSLContextRef)), (UInt8*) &sslContext);
                CFRelease(data);
                
                // TODO: Set the client certificates
#endif
            }
            
            break;
        }
        case kCFStreamEventEndEncountered:
        case kCFStreamEventErrorOccurred:
        {
            // Get the error code
            CFErrorRef error = CFWriteStreamCopyError(stream);
            CFIndex index = CFErrorGetCode(error);
            CFRelease(error);
            
            TSK_DEBUG_INFO("__CFWriteStreamClientCallBack --> Error %lu", index);
            
            TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, sock->fd);
            removeSocket(sock, context);
            break;
        }
        default:
        {
            // Not Implemented
            assert(42 == 0);
            break;
        }
    }
    
    /* unlock context */
    tsk_safeobj_unlock(context);
}
static void *__playback_thread(void *param)
{
	tdav_producer_dsound_t* dsound = (tdav_producer_dsound_t*)param; 

	HRESULT hr;
	LPVOID lpvAudio1, lpvAudio2;
	DWORD dwBytesAudio1, dwBytesAudio2;

	TSK_DEBUG_INFO("__record_thread -- START");

	SetPriorityClass(GetCurrentThread(), REALTIME_PRIORITY_CLASS);

	for(;;){
		DWORD dwEvent = WaitForMultipleObjects(sizeof(dsound->notifEvents)/sizeof(HANDLE), dsound->notifEvents, FALSE, INFINITE);

		if(!dsound->started){
			break;
		}
		else {
			// lock
			if((hr = IDirectSoundCaptureBuffer_Lock(dsound->captureBuffer, (dwEvent * dsound->bytes_per_notif), dsound->bytes_per_notif, &lpvAudio1, &dwBytesAudio1, &lpvAudio2, &dwBytesAudio2, 0)) != DS_OK){
				tdav_win32_print_error("IDirectSoundCaptureBuffer_Lock", hr);
				goto next;
			}

			if(TMEDIA_PRODUCER(dsound)->enc_cb.callback){
				if(lpvAudio2){
					TMEDIA_PRODUCER(dsound)->enc_cb.callback(TMEDIA_PRODUCER(dsound)->enc_cb.callback_data, lpvAudio1, dwBytesAudio1);
					TMEDIA_PRODUCER(dsound)->enc_cb.callback(TMEDIA_PRODUCER(dsound)->enc_cb.callback_data, lpvAudio2, dwBytesAudio2);
				}
				else{
					TMEDIA_PRODUCER(dsound)->enc_cb.callback(TMEDIA_PRODUCER(dsound)->enc_cb.callback_data, lpvAudio1, dwBytesAudio1);
				}
			}

			// unlock
			if((hr = IDirectSoundCaptureBuffer_Unlock(dsound->captureBuffer, lpvAudio1, dwBytesAudio1, lpvAudio2, dwBytesAudio2)) != DS_OK){
				tdav_win32_print_error("IDirectSoundCaptureBuffer_Unlock", hr);
				goto next;
			}
next:;
		}
	}

	TSK_DEBUG_INFO("__record_thread -- STOP");
	

	return tsk_null;
}
/*== Add new socket ==*/
int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client)
{
	transport_context_t *context = transport?transport->context:0;
	if (context) {
		transport_socket_t *sock = tsk_calloc(1, sizeof(transport_socket_t));
		sock->fd = fd;
		sock->type = type;
		sock->owner = take_ownership;

        // TODO: Find out how to specify client certificate
		//if (TNET_SOCKET_TYPE_IS_TLS(sock->type)) {
		//	sock->tlshandle = tnet_sockfd_set_tlsfiles(sock->fd, is_client, transport->tls.ca, transport->tls.pvk, transport->tls.pbk);
		//}
		
		tsk_safeobj_lock(context);
        
		context->sockets[context->count] = sock;
		context->count++;
		
		tsk_safeobj_unlock(context);
		
		TSK_DEBUG_INFO("Socket added");
		
		return 0;
	}
	else{
		TSK_DEBUG_ERROR("Context is Null.");
		return -1;
	}
}
int tdav_consumer_audiounit_deinit(tmedia_consumer_t* self)
{
    tdav_consumer_audiounit_t* consumer = (tdav_consumer_audiounit_t*)self;
    if(!consumer) {
        TSK_DEBUG_ERROR("Invalid parameter");
        return -1;
    }
    // Stop
    if (consumer->started) {
        int ret = tdav_audiounit_handle_stop(consumer->audioUnitHandle);
        if (ret) {
            TSK_DEBUG_ERROR("tdav_audiounit_handle_stop failed with error code=%d", ret);
        }
        consumer->started = tsk_false;
    }
    // Destroy handle (will be re-created by the next start)
#if TARGET_OS_IPHONE
    //https://devforums.apple.com/thread/118595
    if (consumer->audioUnitHandle) {
        tdav_audiounit_handle_destroy(&consumer->audioUnitHandle);
    }
#endif
    consumer->ready = tsk_false;
    consumer->paused = tsk_false;
    
    TSK_DEBUG_INFO("AudioUnit consumer deinitialized");
    
    return 0;
}
/*
* Sends dgarm to the specified destionation.
*/
tsk_size_t tnet_transport_sendto(const tnet_transport_handle_t *handle, tnet_fd_t from, const struct sockaddr *to, const void* buf, tsk_size_t size)
{
	tnet_transport_t *transport = (tnet_transport_t*)handle;
	WSABUF wsaBuffer;
	DWORD numberOfBytesSent = 0;
	int ret = -1;

	if (!transport){
		TSK_DEBUG_ERROR("Invalid server handle.");
		return ret;
	}

	if (!TNET_SOCKET_TYPE_IS_DGRAM(transport->master->type)){
		TSK_DEBUG_ERROR("In order to use WSASendTo you must use an udp transport.");
		return ret;
	}

	wsaBuffer.buf = (CHAR*)buf;
	wsaBuffer.len = (ULONG)size;

	if ((ret = WSASendTo(from, &wsaBuffer, 1, &numberOfBytesSent, 0, to, tnet_get_sockaddr_size(to), 0, 0)) == SOCKET_ERROR){
		if ((ret = WSAGetLastError()) == WSA_IO_PENDING){
			TSK_DEBUG_INFO("WSA_IO_PENDING error for WSASendTo SSESSION");
			ret = 0;
		}
		else{
			TNET_PRINT_LAST_ERROR("WSASendTo have failed.");
			return ret;
		}
	}
	else ret = 0;

	return numberOfBytesSent;
}
int tdav_consumer_audio_set(tdav_consumer_audio_t* self, const tmedia_param_t* param)
{
	if(!self){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}

	if(param->plugin_type == tmedia_ppt_consumer){
		if(param->value_type == tmedia_pvt_int32){
			if(tsk_striequals(param->key, "gain")){
				int32_t gain = *((int32_t*)param->value);
				if(gain<TDAV_AUDIO_GAIN_MAX && gain>=0){
					TMEDIA_CONSUMER(self)->audio.gain = (uint8_t)gain;
					TSK_DEBUG_INFO("audio consumer gain=%u", gain);
				}
				else{
					TSK_DEBUG_ERROR("%u is invalid as gain value", gain);
					return -2;
				}
			}
			else if(tsk_striequals(param->key, "volume")){
				TMEDIA_CONSUMER(self)->audio.volume = TSK_TO_INT32((uint8_t*)param->value);
				TMEDIA_CONSUMER(self)->audio.volume = TSK_CLAMP(0, TMEDIA_CONSUMER(self)->audio.volume, 100);
			}
		}
	}

	return 0;
}
Exemple #13
0
int	dummy_pause(tmedia_t* self)
{
	dummy_t *dummy = DUMMY(self);
	TSK_DEBUG_INFO("dummy_pause");

	return 0;
}
Exemple #14
0
int	dummy_stop(tmedia_t* self)
{
	dummy_t *dummy = DUMMY(self);
	TSK_DEBUG_INFO("dummy_stop");
	
	return 0;
}
static tsk_object_t* tnet_transport_dtor(tsk_object_t * self)
{
    tnet_transport_t *transport = self;
    if (transport){
        tnet_transport_set_callback(transport, tsk_null, tsk_null);
        tnet_transport_shutdown(transport);
        TSK_OBJECT_SAFE_FREE(transport->master);
        TSK_OBJECT_SAFE_FREE(transport->context);
        TSK_OBJECT_SAFE_FREE(transport->natt_ctx);
        TSK_FREE(transport->local_ip);
        TSK_FREE(transport->local_host);
        
        // proxy
        TSK_OBJECT_SAFE_FREE(transport->proxy.info);
        
        // (tls and dtls) = ssl
        TSK_FREE(transport->tls.ca);
        TSK_FREE(transport->tls.pbk);
        TSK_FREE(transport->tls.pvk);
        _tnet_transport_ssl_deinit(transport); // openssl contexts
        
        TSK_DEBUG_INFO("*** Transport (%s) destroyed ***", transport->description);
        TSK_FREE(transport->description);
    }
    
    return self;
}
Exemple #16
0
/**@ingroup tsk_object_group
* Creates new object. The object MUST be declared using @ref TSK_DECLARE_OBJECT macro.
* @param objdef The object meta-data (definition). For more infomation see @ref tsk_object_def_t.
* @param ... List of parameters to pass to the constructor(defined in the meta-data).
* @retval @ref tsk_object_t object with a reference counter equal to 1.
* @sa @ref tsk_object_new_2.
*/
tsk_object_t* tsk_object_new(const tsk_object_def_t *objdef, ...)
{
	// Do not check "objdef", let the application die if it's null
	tsk_object_t *newobj = tsk_calloc(1, objdef->size);
	if(newobj){
		(*(const tsk_object_def_t **) newobj) = objdef;
		TSK_OBJECT_HEADER(newobj)->refCount = 1;
		if(objdef->constructor){ 
			va_list ap;
			tsk_object_t * newobj_ = newobj;// save
			va_start(ap, objdef);
			newobj = objdef->constructor(newobj, &ap); // must return new
			va_end(ap);

			if(!newobj){ // null if constructor failed to initialized the object
				if(objdef->destructor){
					objdef->destructor(newobj_);
				}
				tsk_free(&newobj_);
			}

#if TSK_DEBUG_OBJECTS
		TSK_DEBUG_INFO("N∞ objects:%d", ++tsk_objects_count);
#endif
		}
		else{
			TSK_DEBUG_WARN("No constructor found.");
		}
	}
	else{
		TSK_DEBUG_ERROR("Failed to create new tsk_object.");
	}

	return newobj;
}
/* destructor */
static tsk_object_t* tdav_producer_audiounit_dtor(tsk_object_t * self)
{ 
	tdav_producer_audiounit_t *producer = self;
	if(producer){
		// Stop the producer if not done
		if(producer->started){
			tdav_producer_audiounit_stop(self);
		}
		
		// Free all buffers and dispose the queue
        if (producer->audioUnitHandle) {
			tdav_audiounit_handle_destroy(&producer->audioUnitHandle);
        }
        TSK_FREE(producer->ring.chunck.buffer);
		if(producer->ring.buffer){
			speex_buffer_destroy(producer->ring.buffer);
		}
		/* deinit base */
		tdav_producer_audio_deinit(TDAV_PRODUCER_AUDIO(producer));
        
        TSK_DEBUG_INFO("*** AudioUnit Producer destroyed ***");
	}
	
	return self;
}
static int tdav_producer_audiounit_start(tmedia_producer_t* self)
{
	tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)self;
	
    if(!producer){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}
	if(producer->paused){
		producer->paused = tsk_false;
		return tsk_false;
	}
	
	int ret;
	if(producer->started){
		TSK_DEBUG_WARN("Already started");
		return 0;
	}
	else {
		ret = tdav_audiounit_handle_start(producer->audioUnitHandle);
		if(ret){
			TSK_DEBUG_ERROR("tdav_audiounit_handle_start failed with error code=%d", ret);
			return ret;
		}
	}
	producer->started = tsk_true;
    
    // apply parameters (because could be lost when the producer is restarted -handle recreated-)
    ret = tdav_audiounit_handle_mute(producer->audioUnitHandle, producer->muted);

	TSK_DEBUG_INFO("AudioUnit producer started");
	return 0;
}
Exemple #19
0
/**@ingroup tnet_socket_group
 * @retval	Zero if succeed and nonzero error code otherwise.
 */
int tnet_socket_handle_brokenpipe(tnet_socket_t* self)
{
    int ret;
    tnet_fd_t fd_old, fd_new;
    if (!self || !TNET_SOCKET_TYPE_IS_DGRAM(self->type)) { // Must be UDP
        TSK_DEBUG_ERROR("Invalid parameter");
        return -1;
    }
    fd_old = self->fd;
    fd_new = TNET_INVALID_FD;
    
    // close old fd
    ret = tnet_sockfd_close(&self->fd);
    // try to create an fd binding to the same address
    if ((ret = tnet_sockfd_init(self->ip, self->port, self->type, &fd_new)) != 0) {
        TNET_PRINT_LAST_ERROR("Find to bind to %s:%d", self->ip, self->port);
        // TODO: Create completly new socket?
        return ret;
    }
#if TNET_UNDER_IPHONE || TNET_UNDER_IPHONE_SIMULATOR
    /* disable SIGPIPE signal */
    {
        int yes = 1;
        if (setsockopt(fd_new, SOL_SOCKET, SO_NOSIGPIPE, (char*)&yes, sizeof(int))){
            TNET_PRINT_LAST_ERROR("setsockopt(%d, SO_NOSIGPIPE) have failed", fd_new);
        }
    }
#endif /* TNET_UNDER_IPHONE || TNET_UNDER_IPHONE_SIMULATOR */
    TSK_DEBUG_INFO("Broken pipe result for {%s:%d}: %d -> %d", self->ip, self->port, fd_old, fd_new);
    self->fd = fd_new;
    return 0;
}
/* Remove socket
*/
int tnet_transport_remove_socket(const tnet_transport_handle_t *handle, tnet_fd_t* fd)
{
    tnet_transport_t *transport = (tnet_transport_t*)handle;
    transport_context_t *context;
    int ret = -1;
    tsk_size_t i;
    tsk_bool_t found = tsk_false;

    if (!transport || !(context = (transport_context_t*)transport->context)) {
        TSK_DEBUG_ERROR("Invalid parameter");
        return -1;
    }

    for (i = 0; i < context->count; i++) {
        if (context->sockets[i]->fd == *fd) {
            removeSocket((int)i, context);
            found = tsk_true;
            TSK_RUNNABLE_ENQUEUE(transport, event_removed, transport->callback_data, *fd);
            *fd = TNET_INVALID_FD;
            break;
        }
    }

    if (found) {
        /* Signal */
        if (WSASetEvent(context->events[0])) {
            TSK_DEBUG_INFO("Old socket removed from the network transport.");
            return 0;
        }
    }

    // ...

    return -1;
}
static int tdav_consumer_audiounit_start(tmedia_consumer_t* self)
{
	tdav_consumer_audiounit_t* consumer = (tdav_consumer_audiounit_t*)self;
	
    if(!consumer){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}
	if(consumer->paused){
		consumer->paused = tsk_false;
	}
	if(consumer->started){
		TSK_DEBUG_WARN("Already started");
		return 0;
	}
	else {
		int ret = tdav_audiounit_handle_start(consumer->audioUnitHandle);
		if(ret){
			TSK_DEBUG_ERROR("tdav_audiounit_handle_start failed with error code=%d", ret);
			return ret;
		}
	}
	consumer->started = tsk_true;
	TSK_DEBUG_INFO("AudioUnit consumer started");
	return 0;
}
/** Initialize audio consumer */
int tdav_consumer_audio_init(tdav_consumer_audio_t* self)
{
	int ret;

	TSK_DEBUG_INFO("tdav_consumer_audio_init()");

	if(!self){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}
	/* base */
	if((ret = tmedia_consumer_init(TMEDIA_CONSUMER(self)))){
		return ret;
	}

	/* self (should be update by prepare() by using the codec's info)*/
	TMEDIA_CONSUMER(self)->audio.bits_per_sample = TDAV_BITS_PER_SAMPLE_DEFAULT;
	TMEDIA_CONSUMER(self)->audio.ptime = TDAV_PTIME_DEFAULT;
	TMEDIA_CONSUMER(self)->audio.in.channels = TDAV_CHANNELS_DEFAULT;
	TMEDIA_CONSUMER(self)->audio.in.rate = TDAV_RATE_DEFAULT;
	TMEDIA_CONSUMER(self)->audio.gain = TSK_MIN(tmedia_defaults_get_audio_consumer_gain(), TDAV_AUDIO_GAIN_MAX);

	tsk_safeobj_init(self);

	return 0;
}
static tsk_size_t tdav_speex_jitterbuffer_get(tmedia_jitterbuffer_t* self, void* out_data, tsk_size_t out_size)
{
	tdav_speex_jitterbuffer_t *jb = (tdav_speex_jitterbuffer_t *)self;
    JitterBufferPacket jb_packet;
    int ret;

    if(!out_data || !out_size){
        TSK_DEBUG_ERROR("Invalid parameter");
        return 0;
    }
    if(!jb->state){
        TSK_DEBUG_ERROR("Invalid state");
        return 0;
    }
	if(jb->x_data_size != out_size){ // consumer must request PTIME data
		TSK_DEBUG_WARN("%d not expected as frame size. %u<>%u", out_size, jb->frame_duration, (out_size * 500)/jb->rate);
		return 0;
	}

    jb_packet.data = out_data;
    jb_packet.len = out_size;

	if ((ret = jitter_buffer_get(jb->state, &jb_packet, jb->frame_duration/*(out_size * 500)/jb->rate*/, tsk_null)) != JITTER_BUFFER_OK) {
        switch(ret){
            case JITTER_BUFFER_MISSING: /*TSK_DEBUG_INFO("JITTER_BUFFER_MISSING - %d", ret);*/ break;
            case JITTER_BUFFER_INSERTION: /*TSK_DEBUG_INFO("JITTER_BUFFER_INSERTION - %d", ret);*/ break;
            default: TSK_DEBUG_INFO("jitter_buffer_get() failed - %d", ret); break;
        }
        jitter_buffer_update_delay(jb->state, &jb_packet, NULL);
        return 0;
    }
    // jitter_buffer_update_delay(jitterbuffer->state, &jb_packet, NULL);

    return out_size;
}
Exemple #24
0
int tdav_codec_set_priority(tdav_codec_id_t codec_id, int priority)
{
    tsk_size_t i;

    if(priority < 0) {
        TSK_DEBUG_ERROR("Invalid parameter");
        return -1;
    }
    for(i = 0; i < __codec_plugins_all_count && __codec_plugins_all[i]; ++i) {
        if(__codec_plugins_all[i]->codec_id == codec_id) {
            const struct tmedia_codec_plugin_def_s *codec_decl_1, *codec_decl_2;
            priority = TSK_MIN(priority, (int)__codec_plugins_all_count-1);
            codec_decl_1 = __codec_plugins_all[priority];
            codec_decl_2 = __codec_plugins_all[i];

            __codec_plugins_all[i] = codec_decl_1;
            __codec_plugins_all[priority] = codec_decl_2;

            // change priority if already registered and supported
            if(_tdav_codec_is_supported((tdav_codec_id_t)codec_decl_2->codec_id, codec_decl_2) && tmedia_codec_plugin_is_registered(codec_decl_2)) {
                return tmedia_codec_plugin_register_2(codec_decl_2, priority);
            }
            return 0;
        }
    }

    TSK_DEBUG_INFO("Cannot find codec with id=%d for priority setting", codec_id);
    return 0;
}
Exemple #25
0
int tmedia_codec_video_clamp_out_size_to_range_max(tmedia_codec_video_t *self)
{
    int ret = 0;
    if (!self) {
        TSK_DEBUG_ERROR("Invalid parameter");
        return -1;
    }
    if (tmedia_defaults_get_adapt_video_size_range_enabled()) {
        tmedia_pref_video_size_t min, max;
        if ((ret = tmedia_defaults_get_pref_video_size_range(&min, &max)) == 0) {
            unsigned width, height;
            // clip(max)
            if ((ret = tmedia_video_get_size(max, &width, &height)) == 0) {
                unsigned new_width = TSK_CLAMP(0, self->out.width, width);
                unsigned new_height = TSK_CLAMP(0, self->out.height, height);
                TSK_DEBUG_INFO("Pref. video size range defined, video size clipped (%ux%u)->(%ux%u)",
                               width, height,
                               self->out.width, self->out.height);
                self->out.width = width;
                self->out.height = height;
            }
            // no clip(min) as we cannot increase the size to more than what was negotiated without sending reINVITE
        }
    }
    return ret;
}
Exemple #26
0
/*== Add new socket ==*/
int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client)
{
	transport_context_t *context = transport?transport->context:0;
	if(context){
		transport_socket_xt *sock = tsk_calloc(1, sizeof(transport_socket_xt));
		sock->fd = fd;
		sock->type = type;
		sock->owner = take_ownership;

		if((TNET_SOCKET_TYPE_IS_TLS(sock->type) || TNET_SOCKET_TYPE_IS_WSS(sock->type)) && transport->tls.enabled){
#if HAVE_OPENSSL
			sock->tlshandle = tnet_tls_socket_create(sock->fd, is_client ? transport->tls.ctx_client : transport->tls.ctx_server);       
#endif
		}
		
		tsk_safeobj_lock(context);
		
		context->ufds[context->count].fd = fd;
		context->ufds[context->count].events = (fd == context->pipeR) ? TNET_POLLIN : context->events;
		context->ufds[context->count].revents = 0;
		context->sockets[context->count] = sock;
		
		context->count++;
		
		tsk_safeobj_unlock(context);
		
		TSK_DEBUG_INFO("Socket added: fd=%d, tail.count=%d", fd, context->count);
		
		return 0;
	}
	else{
		TSK_DEBUG_ERROR("Context is Null.");
		return -1;
	}
}
Exemple #27
0
/**@ingroup tmedia_codec_group
* UnRegisters a codec plugin.
* @param plugin the definition of the plugin.
* @retval 0 if succeed and non-zero error code otherwise.
*/
int tmedia_codec_plugin_unregister(const tmedia_codec_plugin_def_t* plugin)
{
    tsk_size_t i;
    tsk_bool_t found = tsk_false;
    if(!plugin) {
        TSK_DEBUG_ERROR("Invalid Parameter");
        return -1;
    }

    /* find the plugin to unregister */
    for(i = 0; i<TMED_CODEC_MAX_PLUGINS && __tmedia_codec_plugins[i]; i++) {
        if(__tmedia_codec_plugins[i] == plugin) {
            TSK_DEBUG_INFO("UnRegister codec: %s, %s", plugin->name, plugin->desc);
            __tmedia_codec_plugins[i] = tsk_null;
            found = tsk_true;
            break;
        }
    }

    /* compact */
    if(found) {
        for(; i<(TMED_CODEC_MAX_PLUGINS - 1); i++) {
            if(__tmedia_codec_plugins[i+1]) {
                __tmedia_codec_plugins[i] = __tmedia_codec_plugins[i+1];
            }
            else {
                break;
            }
        }
        __tmedia_codec_plugins[i] = tsk_null;
    }
    return (found ? 0 : -2);
}
Exemple #28
0
static tsk_object_t* tnet_dtls_socket_dtor(tsk_object_t * self)
{
	tnet_dtls_socket_t *socket = self;
	if (socket){
#if HAVE_OPENSSL
		if (socket->rbio) {
			//BIO_free(socket->rbio);
			socket->rbio = tsk_null;
		}
		if (socket->wbio) {
			//BIO_free(socket->wbio);
			socket->wbio = tsk_null;
		}
		if (socket->ssl) {
			SSL_shutdown(socket->ssl);
			// https://www.openssl.org/docs/crypto/BIO_s_bio.html
			// implicitly frees internal_bio
			SSL_free(socket->ssl);
		}
#endif
		TSK_FREE(socket->handshake_data.ptr);
		TSK_OBJECT_SAFE_FREE(socket->wrapped_sock);
		tsk_safeobj_deinit(socket);

		TSK_DEBUG_INFO("*** tnet_dtls_socket_t destroyed ***");
	}
	return self;
}
static void *__sender_thread(void *param)
{
	TSK_DEBUG_INFO("__sender_thread::ENTER");
	
	tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)param;
	uint32_t ptime = TMEDIA_PRODUCER(producer)->audio.ptime;
	tsk_ssize_t avail;
	
	// interval to sleep when using nonosleep() instead of conditional variable
	struct timespec interval;
	interval.tv_sec = (long)(ptime/1000); 
	interval.tv_nsec = (long)(ptime%1000) * 1000000; 
	
	// change thread priority
//#if TARGET_OS_IPHONE
	__sender_thread_set_realtime(TMEDIA_PRODUCER(producer)->audio.ptime);
//#endif
	
	// starts looping
	for (;;) {
		// wait for "ptime" milliseconds
		if(ptime <= kMaxPtimeBeforeUsingCondVars){
			nanosleep(&interval, 0);
		}
		else {
			tsk_condwait_timedwait(producer->senderCondWait, (uint64_t)ptime);
		}
		// check state
		if(!producer->started){
			break;
		}
		// read data and send them
		if(TMEDIA_PRODUCER(producer)->enc_cb.callback) {
			tsk_mutex_lock(producer->ring.mutex);
			avail = speex_buffer_get_available(producer->ring.buffer);
			while (producer->started && avail >= producer->ring.chunck.size) {
				avail -= speex_buffer_read(producer->ring.buffer, producer->ring.chunck.buffer, producer->ring.chunck.size);
				TMEDIA_PRODUCER(producer)->enc_cb.callback(TMEDIA_PRODUCER(producer)->enc_cb.callback_data, 
														   producer->ring.chunck.buffer, producer->ring.chunck.size);
			}
			tsk_mutex_unlock(producer->ring.mutex);
		}
		else;
	}
	TSK_DEBUG_INFO("__sender_thread::EXIT");
	return tsk_null;
}
Exemple #30
0
tnet_dtls_socket_handle_t* tnet_dtls_socket_create(struct tnet_socket_s* wrapped_sock, struct ssl_ctx_st* ssl_ctx)
{
#if !HAVE_OPENSSL || !HAVE_OPENSSL_DTLS
	TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
	return tsk_null;
#else
	tnet_dtls_socket_t* socket;

	if (!wrapped_sock || !ssl_ctx){
		TSK_DEBUG_ERROR("Invalid parameter");
		return tsk_null;
	}
	if ((socket = tsk_object_new(tnet_dtls_socket_def_t))) {
		const tsk_bool_t set_mtu = TNET_SOCKET_TYPE_IS_DGRAM(wrapped_sock->type) || 1; //!\ This is required even if the local transport is TCP/TLS because the relayed (TURN) transport could be UDP
		socket->wrapped_sock = tsk_object_ref(wrapped_sock);
		if (!(socket->ssl = SSL_new(ssl_ctx))) {
			TSK_DEBUG_ERROR("SSL_new(CTX) failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
			TSK_OBJECT_SAFE_FREE(socket);
			return tsk_null;
		}
		if (set_mtu) {
			SSL_set_options(socket->ssl, SSL_OP_NO_QUERY_MTU);
			SSL_set_mtu(socket->ssl, TNET_DTLS_MTU - 28);
			socket->ssl->d1->mtu = TNET_DTLS_MTU - 28;
		}
		if (!(socket->rbio = BIO_new(BIO_s_mem())) || !(socket->wbio = BIO_new(BIO_s_mem()))){
			TSK_DEBUG_ERROR("BIO_new_socket(%d) failed [%s]", socket->wrapped_sock->fd, ERR_error_string(ERR_get_error(), tsk_null));
			if (socket->rbio){
				BIO_free(socket->rbio);
			}
			if (socket->wbio){
				BIO_free(socket->wbio);
			}
			TSK_OBJECT_SAFE_FREE(socket);
			return tsk_null;
		}
		BIO_set_mem_eof_return(socket->rbio, -1);
		BIO_set_mem_eof_return(socket->wbio, -1);
		SSL_set_bio(socket->ssl, socket->rbio, socket->wbio);
		SSL_set_mode(socket->ssl, SSL_MODE_AUTO_RETRY);
		SSL_set_read_ahead(socket->ssl, 1);
		if (set_mtu) {
			BIO_ctrl(SSL_get_wbio(socket->ssl), BIO_CTRL_DGRAM_SET_MTU, TNET_DTLS_MTU - 28, NULL);
		}

		if ((socket->verify_peer = (SSL_CTX_get_verify_mode(ssl_ctx) != SSL_VERIFY_NONE))){
			TSK_DEBUG_INFO("SSL cert verify: ON");
			socket->verify_peer = tsk_true;
			SSL_set_verify(socket->ssl, (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), _tnet_dtls_verify_cert);
		}
		else {
			TSK_DEBUG_ERROR("Verity not enabled");
		}

		SSL_set_app_data(socket->ssl, socket);
	}
	return socket;
#endif
}