Exemplo n.º 1
0
/**@ingroup tsk_condwait_group
* Wakes up all threads that are currently waiting for the condition.
* @param handle CondWait handle created using @ref tsk_condwait_create.
* @retval Zero if succeed and non-zero otherwise.
* @sa @ref tsk_condwait_signal.
*/
int tsk_condwait_broadcast(tsk_condwait_handle_t* handle)
{
	int ret = EINVAL;
	tsk_condwait_t *condwait = (tsk_condwait_t*)handle;
	if(!condwait){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}

#if TSK_UNDER_WINDOWS
	if(ret = ((SetEvent(condwait->pcond) && ResetEvent(condwait->pcond)) ? 0 : -1)){
		ret = GetLastError();
		TSK_DEBUG_ERROR("SetEvent function failed: %d", ret);
	}
#else
	if(condwait && condwait->mutex){
		tsk_mutex_lock(condwait->mutex);
		if((ret = pthread_cond_broadcast(condwait->pcond))){
			TSK_DEBUG_ERROR("pthread_cond_broadcast function failed: %d", ret);
		}
		tsk_mutex_unlock(condwait->mutex);
	}
#endif

	return ret;
}
static OSStatus __handle_output_buffer(void *inRefCon, 
								 AudioUnitRenderActionFlags *ioActionFlags, 
								 const AudioTimeStamp *inTimeStamp, 
								 UInt32 inBusNumber, 
								 UInt32 inNumberFrames, 
								 AudioBufferList *ioData) {
	OSStatus status = noErr;
	// tsk_size_t out_size;
	tdav_consumer_audiounit_t* consumer = (tdav_consumer_audiounit_t* )inRefCon;
	
	if(!consumer->started || consumer->paused){
		goto done;
	}
	
	if(!ioData){
		TSK_DEBUG_ERROR("Invalid argument");
		status = kNoDataError;
		goto done;
	}
	// read from jitter buffer and fill ioData buffers
	tsk_mutex_lock(consumer->ring.mutex);
	for(int i=0; i<ioData->mNumberBuffers; i++){
		/* int ret = */ tdav_consumer_audiounit_get(consumer, ioData->mBuffers[i].mData, ioData->mBuffers[i].mDataByteSize);
	}
	tsk_mutex_unlock(consumer->ring.mutex);
	
done:	
    return status;
}
Exemplo n.º 3
0
/**@ingroup tsk_condwait_group
* Block the current thread until the condition is opened. 
* @param handle CondWait handle created using @ref tsk_condwait_create.
* @retval Zero if succeed and non-zero otherwise.
* @sa @ref tsk_condwait_timedwait.
*/
int tsk_condwait_wait(tsk_condwait_handle_t* handle)
{
	int ret = EINVAL;
	tsk_condwait_t *condwait = (tsk_condwait_t*)handle;
	if(!condwait){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}

#if TSK_UNDER_WINDOWS
	if((ret = (WaitForSingleObject(condwait->pcond, INFINITE) == WAIT_FAILED) ? -1 : 0)){
		TSK_DEBUG_ERROR("WaitForSingleObject function failed: %d", ret);
	}
#else
	if(condwait && condwait->mutex){
		tsk_mutex_lock(condwait->mutex);
		if((ret = pthread_cond_wait(condwait->pcond, (pthread_mutex_t*)condwait->mutex)))
		{
			TSK_DEBUG_ERROR("pthread_cond_wait function failed: %d", ret);
		}
		tsk_mutex_unlock(condwait->mutex);
	}
#endif
	return ret;
}
Exemplo n.º 4
0
static OSStatus __handle_input_buffer(void *inRefCon, 
                                  AudioUnitRenderActionFlags *ioActionFlags, 
                                  const AudioTimeStamp *inTimeStamp, 
                                  UInt32 inBusNumber, 
                                  UInt32 inNumberFrames, 
                                  AudioBufferList *ioData) {
	OSStatus status = noErr;
	tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)inRefCon;
	
	// holder
	AudioBuffer buffer;
	buffer.mData =  tsk_null;
	buffer.mDataByteSize = 0;
	buffer.mNumberChannels = TMEDIA_PRODUCER(producer)->audio.channels;
	
	// list of holders
	AudioBufferList buffers;
	buffers.mNumberBuffers = 1;
	buffers.mBuffers[0] = buffer;
	
	// render to get frames from the system
	status = AudioUnitRender(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), 
							 ioActionFlags, 
							 inTimeStamp, 
							 inBusNumber, 
							 inNumberFrames, 
							 &buffers);
	if(status == 0){
		tsk_mutex_lock(producer->ring.mutex);
		speex_buffer_write(producer->ring.buffer, buffers.mBuffers[0].mData, buffers.mBuffers[0].mDataByteSize);
		tsk_mutex_unlock(producer->ring.mutex);
	}
	
    return status;
}
Exemplo n.º 5
0
/**@ingroup tsk_list_group
* Locks the @ref tsk_list_t "list" to avoid concurrent access. The @ref tsk_list_t "list" must be unlocked using @ref tsk_list_unlock(). <br />
* For more information about thread-safety see @ref _Anchor_TinySAK_Linked_List_Thread_Safety "here".
* @param list The list to lock.
* @return 0 if succeed and non-zero error code otherwise.
* @sa @ref tsk_list_unlock
*/
int tsk_list_lock(tsk_list_t* list)
{
	if(list){
		if(!list->mutex){
			list->mutex = tsk_mutex_create();
		}
		return tsk_mutex_lock(list->mutex);
	}
	else{
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}
}
Exemplo n.º 6
0
/**@ingroup tsk_condwait_group
* Block the current thread until the condition is opened or until @a ms milliseconds have passed. 
* @param handle condwait handle created using @ref tsk_condwait_create.
* @param ms The number of milliseconds to wait for a given condition.
* @retval Zero if succeed and non-zero error code otherwise.
* @sa @ref tsk_condwait_wait.
*/
int tsk_condwait_timedwait(tsk_condwait_handle_t* handle, uint64_t ms)
{
#if TSK_UNDER_WINDOWS
	DWORD ret = WAIT_FAILED;
#else
	int ret = EINVAL;
#endif
	tsk_condwait_t *condwait = (tsk_condwait_t*)handle;

#if TSK_UNDER_WINDOWS
	if((ret = WaitForSingleObject(condwait->pcond, (DWORD)ms)) != WAIT_OBJECT_0){
		if(ret == TIMED_OUT){
			/* TSK_DEBUG_INFO("WaitForSingleObject function timedout: %d", ret); */
		}
		else{
			TSK_DEBUG_ERROR("WaitForSingleObject function failed: %d", ret);
		}
		return ((ret == TIMED_OUT) ? 0 : ret);
	}
#else
	if(condwait && condwait->mutex){
		struct timespec   ts = {0, 0};
		struct timeval    tv = {0, 0};
		/*int rc =*/  tsk_gettimeofday(&tv, 0);

		ts.tv_sec  = ( tv.tv_sec + ((long)ms/1000) );
		ts.tv_nsec += ( (tv.tv_usec * 1000) + ((long)ms % 1000 * 1000000) );
		if(ts.tv_nsec > 999999999) ts.tv_sec+=1, ts.tv_nsec = ts.tv_nsec % 1000000000;
		
		tsk_mutex_lock(condwait->mutex);
		if((ret = pthread_cond_timedwait(condwait->pcond, (pthread_mutex_t*)condwait->mutex, &ts))){
			if(ret == TIMED_OUT){
				/* TSK_DEBUG_INFO("pthread_cond_timedwait function timedout: %d", ret); */
			}
			else{
				TSK_DEBUG_ERROR("pthread_cond_timedwait function failed: %d", ret);
			}
		}

		tsk_mutex_unlock(condwait->mutex);

		return ((ret == TIMED_OUT) ? 0 : ret);
	}
#endif

	return ret;
}
Exemplo n.º 7
0
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;
}
static int tdav_consumer_audiounit_consume(tmedia_consumer_t* self, const void* buffer, tsk_size_t size, const tsk_object_t* proto_hdr)
{	
	tdav_consumer_audiounit_t* consumer = (tdav_consumer_audiounit_t*)self;
	if(!consumer || !buffer || !size){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}
#if DISABLE_JITTER_BUFFER
	{
		if(consumer->ring.buffer){
			tsk_mutex_lock(consumer->ring.mutex);
			speex_buffer_write(consumer->ring.buffer, (void*)buffer, size);
			tsk_mutex_unlock(consumer->ring.mutex);
			return 0;
		}
		return -2;
	}
#else
	{
		return tdav_consumer_audio_put(TDAV_CONSUMER_AUDIO(consumer), buffer, size, proto_hdr);
	}
#endif
}