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; }
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; }
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; }
int dummy_pause(tmedia_t* self) { dummy_t *dummy = DUMMY(self); TSK_DEBUG_INFO("dummy_pause"); return 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; }
/**@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; }
/**@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; }
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; }
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; }
/*== 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; } }
/**@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); }
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; }
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 }