Пример #1
0
GF_EXPORT
GF_Err gf_th_run(GF_Thread *t, u32 (*Run)(void *param), void *param)
{
	TBuf<32>	threadName;

	const TUint KThreadMinHeapSize = 0x1000;
	const TUint KThreadMaxHeapSize = 0x10000;

	if (!t || t->Run || t->_signal) return GF_BAD_PARAM;
	t->Run = Run;
	t->args = param;
	t->_signal = gf_sema_new(1, 0);
	if (! t->_signal) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Unable to create thread start-up semaphore\n"));
		t->status = GF_THREAD_STATUS_DEAD;
		return GF_IO_ERR;
	}

	threadName.Format(_L("GTH%d"), (u32) t);
	t->threadH = new RThread();
	if ( t->threadH->Create(threadName, (TThreadFunction)RunThread, KDefaultStackSize, KThreadMinHeapSize, KThreadMaxHeapSize, (void *)t, EOwnerProcess) != KErrNone) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Unable to create thread\n"));
		t->status = GF_THREAD_STATUS_DEAD;
		return GF_IO_ERR;
	}
	t->threadH->Resume();

	/*wait for the child function to call us - do NOT return before, otherwise the thread status would
	be unknown*/
	//GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Waiting for thread to start\n"));
	gf_sema_wait(t->_signal);
	gf_sema_del(t->_signal);
	t->_signal = NULL;
	return GF_OK;
}
Пример #2
0
void gf_es_dispatch_raw_media_au(GF_Channel *ch, char *payload, u32 payload_size, u32 cts)
{
	GF_CompositionMemory *cb;
	GF_CMUnit *cu;
	if (!payload || !ch->odm->codec->CB) return;
	if (!ch->odm->codec->CB->no_allocation) return;

	cb = ch->odm->codec->CB;
	cu = gf_cm_lock_input(cb, cts, 1);
	if (cu) {
		u32 size = 0;
		assert(cu->RenderedLength==0);
		if (cb->UnitSize >= payload_size) {
			cu->data = payload;
			size = payload_size;
			cu->TS = cts;
			GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[ODM%d] Raw Frame dispatched to CB - TS %d ms\n", ch->odm->OD->objectDescriptorID, cu->TS));
		}
		gf_cm_unlock_input(cb, cu, size, 1);

		if (ch->BufferOn) {
			ch->BufferOn = 0;
			gf_clock_buffer_off(ch->clock);
			gf_cm_abort_buffering(cb);
		}
		/*since the CB is a simple pointer to the input frame, wait until it is released before getting 
		back to the caller module*/
		if (size) {
			gf_sema_wait(ch->odm->raw_frame_sema);
			assert(cb->output->dataLength == 0);
		}
	}
}
Пример #3
0
int dc_consumer_lock(Consumer *consumer, CircularBuffer *circular_buf)
{
	Node *node = &circular_buf->list[consumer->idx];

	gf_mx_p(node->mutex);
	GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("consumer %s enters lock %d\n", consumer->name, consumer->idx));
	if (node->marked == 2) {
		gf_mx_v(node->mutex);
		return -1;
	}

	node->num_consumers_waiting++;
	while (node->num_producers || !node->marked) {
		gf_mx_v(node->mutex);
		gf_sema_wait(node->consumers_semaphore);
		gf_mx_p(node->mutex);

		if (node->marked == 2) {
			gf_mx_v(node->mutex);
			return -1;
		}
	}
	node->num_consumers_waiting--;

	if (node->marked == 2) {
		gf_mx_v(node->mutex);
		return -1;
	}
	node->num_consumers++;
	node->num_consumers_accessed++;
	GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("consumer %s exits lock %d \n", consumer->name, consumer->idx));
	gf_mx_v(node->mutex);

	return 0;
}
Пример #4
0
int dc_producer_lock(Producer *producer, CircularBuffer *circular_buf)
{
	Node *node = &circular_buf->list[producer->idx];

	gf_mx_p(node->mutex);
	GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("producer %s enters lock %d \n", producer->name, producer->idx));

	if ( (circular_buf->mode == LIVE_CAMERA || circular_buf->mode == LIVE_MEDIA) && (node->num_consumers || node->marked)) {
		gf_mx_v(node->mutex);
		return -1;
	}

	while (node->num_consumers || node->marked) {
		gf_mx_v(node->mutex);
		gf_sema_wait(node->producers_semaphore);
		gf_mx_p(node->mutex);
	}

	node->num_producers++;
	if (circular_buf->size>1) {
		node->marked = 1;
	}

	GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("producer %s exits lock %d \n", producer->name, producer->idx));
	gf_mx_v(node->mutex);

	return 0;
}
Пример #5
0
void gf_es_dispatch_raw_media_au(GF_Channel *ch, char *payload, u32 payload_size, u32 cts)
{
	u32 now;
	GF_CompositionMemory *cb;
	GF_CMUnit *cu;
	if (!payload || !ch->odm->codec->CB) return;
	if (!ch->odm->codec->CB->no_allocation) return;

	now = gf_clock_real_time(ch->clock);
	if (cts + ch->MinBuffer < now) {
		if (ch->MinBuffer && (ch->is_raw_channel==2)) {
			ch->clock->clock_init = 0;
			gf_clock_set_time(ch->clock, cts);
			GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[ODM%d] Raw Frame dispatched at OTB %d but frame TS is %d ms - adjusting clock\n", ch->odm->OD->objectDescriptorID, now, cts));
		} else {
			GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[ODM%d] Raw Frame dispatched at OTB %d but frame TS is %d ms - DROPPING\n", ch->odm->OD->objectDescriptorID, now, cts));
		}
		return;
	}

	cb = ch->odm->codec->CB;
	cu = gf_cm_lock_input(cb, cts, 1);
	if (cu) {
		u32 size = 0;
		assert(cu->RenderedLength==0);
		if (cb->UnitSize >= payload_size) {
			cu->data = payload;
			size = payload_size;
			cu->TS = cts;
			GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[ODM%d] Raw Frame dispatched to CB - TS %d ms - OTB %d ms - OTB_drift %d ms\n", ch->odm->OD->objectDescriptorID, cu->TS, gf_clock_real_time(ch->clock), gf_clock_time(ch->clock) ));
		}
		gf_cm_unlock_input(cb, cu, size, 1);

		if (ch->BufferOn) {
			ch->BufferOn = 0;
			gf_clock_buffer_off(ch->clock);
			gf_cm_abort_buffering(cb);
		}
		/*since the CB is a simple pointer to the input frame, wait until it is released before getting 
		back to the caller module*/
		if (size) {
			gf_sema_wait(ch->odm->raw_frame_sema);
			assert(cb->output->dataLength == 0);
		}
	}
}
Пример #6
0
GF_Err gf_th_run(GF_Thread *t, u32 (*Run)(void *param), void *param)
{
#ifdef WIN32
	DWORD id;
#else
	pthread_attr_t att;
#endif
	if (!t || t->Run || t->_signal) return GF_BAD_PARAM;
	t->Run = Run;
	t->args = param;
	t->_signal = gf_sema_new(1, 0);

#ifdef WIN32
	t->threadH = CreateThread(NULL,  t->stackSize, &(RunThread), (void *)t, 0, &id);
	if (t->threadH == NULL) {
#else
	if ( pthread_attr_init(&att) != 0 ) return GF_IO_ERR;
	pthread_attr_setdetachstate(&att, PTHREAD_CREATE_JOINABLE);
	if ( pthread_create(&t->threadH, &att, RunThread, t) != 0 ) {
#endif
		t->status = GF_THREAD_STATUS_DEAD;
		return GF_IO_ERR;
	}

	/*wait for the child function to call us - do NOT return before, otherwise the thread status would
	be unknown*/
	gf_sema_wait(t->_signal);
	gf_sema_del(t->_signal);
	t->_signal = NULL;
	return GF_OK;
}


/* Stops a thread. If Destroy is not 0, thread is destroyed DANGEROUS as no cleanup */
void Thread_Stop(GF_Thread *t, Bool Destroy)
{
	if (gf_th_status(t) == GF_THREAD_STATUS_RUN) {
#ifdef WIN32
		if (Destroy) {
			DWORD dw = 1;
			BOOL ret = TerminateThread(t->threadH, dw);
			if (!ret) {
				DWORD err = GetLastError();
				GF_LOG(GF_LOG_ERROR, GF_LOG_MUTEX, ("[Thread %s] Couldn't stop thread ID 0x%08x, error code %d\n", t->log_name, t->id, err));
			}
			t->threadH = NULL;
		} else {
			WaitForSingleObject(t->threadH, INFINITE);
		}
#else
		if (Destroy) {
#ifdef GPAC_ANDROID
			if (pthread_kill(t->threadH, SIGQUIT))
#else
			if (pthread_cancel(t->threadH))
#endif
				GF_LOG(GF_LOG_ERROR, GF_LOG_MUTEX, ("[Thread %s] Couldn't kill thread ID 0x%08x\n", t->log_name, t->id));
			t->threadH = 0;
		} else {
			/*gracefully wait for Run to finish*/
			if (pthread_join(t->threadH, NULL))
				GF_LOG(GF_LOG_ERROR, GF_LOG_MUTEX, ("[Thread %s] pthread_join() returned an error with thread ID 0x%08x\n", t->log_name, t->id));
		}
#endif
	}
	t->status = GF_THREAD_STATUS_DEAD;
}

void gf_th_stop(GF_Thread *t)
{
	Thread_Stop(t, 0);
}