Esempio n. 1
0
/*drop the output CU*/
void gf_cm_drop_output(GF_CompositionMemory *cb)
{
	assert(cb->UnitCount);
	/*this allows reuse of the CU*/
	cb->output->RenderedLength = 0;
	cb->LastRenderedTS = cb->output->TS;

	/*WARNING: in RAW mode, we (for the moment) only have one unit - setting output->dataLength to 0 means the input is available 
	for the raw channel - we have to make sure the output is completely reseted before releasing the sema*/

	/*on visual streams (except raw oness), always keep the last AU*/
	if (!cb->no_allocation && cb->output->dataLength && (cb->odm->codec->type == GF_STREAM_VISUAL) ) {
		if ( !cb->output->next->dataLength || (cb->Capacity == 1) )  {
			if (cb->odm->raw_frame_sema) {
				cb->output->dataLength = 0;
				gf_sema_notify(cb->odm->raw_frame_sema, 1);
			}
			return;
		}
	}
	
	/*reset the output*/
	cb->output->dataLength = 0;
	cb->output->TS = 0;
	cb->output = cb->output->next;
	cb->UnitCount -= 1;

	if (!cb->HasSeenEOS && cb->UnitCount <= cb->Min) {
		cb->odm->codec->PriorityBoost = 1;
	}

	if (cb->odm->raw_frame_sema) {
		gf_sema_notify(cb->odm->raw_frame_sema, 1);
	}
}
Esempio n. 2
0
static void *RunThread(void *ptr)
{
	TInt err;
	u32 ret = 0;
	CTrapCleanup * cleanup = NULL;
	GF_Thread *t = (GF_Thread *)ptr;


	CActiveScheduler * scheduler = new CActiveScheduler();
	if (scheduler == NULL) {
		t->status = GF_THREAD_STATUS_DEAD;
		gf_sema_notify(t->_signal, 1);
		goto exit;
	}
#ifndef GPAC_DISABLE_LOG
	GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Thread %s] Installing ActiveScheduler\n", t->log_name));
#endif
	CActiveScheduler::Install(scheduler);

#ifndef GPAC_DISABLE_LOG
	GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Thread %s] Creating cleanup trap\n", t->log_name));
#endif
	cleanup = CTrapCleanup::New();
	if( cleanup == NULL ) {
		t->status = GF_THREAD_STATUS_DEAD;
		gf_sema_notify(t->_signal, 1);
		delete CActiveScheduler::Current();
		goto exit;
	}
#if 0
	CActiveScheduler::Start();
#endif
	/* OK , signal the caller */
	t->status = GF_THREAD_STATUS_RUN;
	gf_sema_notify(t->_signal, 1);
	/* Run our thread */
#ifndef GPAC_DISABLE_LOG
	GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Thread %s] Entering thread proc\n", t->log_name));
#endif
	TRAP(err, ret=t->Run(t->args) );
	//ret = t->Run(t->args);

	delete CActiveScheduler::Current();
	delete cleanup;

exit:
#ifndef GPAC_DISABLE_LOG
	GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Thread %s] Exit\n", t->log_name ));
#endif
	t->status = GF_THREAD_STATUS_DEAD;
	t->Run = NULL;
	t->threadH->Close();
	t->threadH = NULL;
	return (void *)ret;
}
Esempio n. 3
0
int dc_consumer_unlock_previous(Consumer *consumer, CircularBuffer *circular_buf)
{
	int node_idx = (consumer->idx - 1 + consumer->max_idx) % consumer->max_idx;
	int last_consumer = 0;
	Node *node = &circular_buf->list[node_idx];

	gf_mx_p(node->mutex);

	node->num_consumers--;
	if (node->num_consumers < 0)
		node->num_consumers = 0;

	if (node->num_consumers_accessed == circular_buf->max_num_consumers) {
		if (node->marked != 2)
			node->marked = 0;
		node->num_consumers_accessed = 0;
		last_consumer = 1;
	}

	gf_sema_notify(node->producers_semaphore, 1);

	GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("consumer %s unlock %d \n", consumer->name, node_idx));
	gf_mx_v(node->mutex);

	return last_consumer;
}
Esempio n. 4
0
/*Reset composition memory. Note we don't reset the content of each frame since it would lead to green frames 
when using bitmap (visual), where data is not cached*/
void gf_cm_reset(GF_CompositionMemory *cb)
{
	GF_CMUnit *cu;

	gf_odm_lock(cb->odm, 1);
	cu = cb->input;
	cu->RenderedLength = 0;
	if (cu->dataLength && cb->odm->raw_frame_sema)  {
		cu->dataLength = 0;
		gf_sema_notify(cb->odm->raw_frame_sema, 1);
	}
	
	cu->dataLength = 0;
	cu->TS = 0;
	cu = cu->next;
	while (cu != cb->input) {
		cu->RenderedLength = 0;
		cu->TS = 0;
		cu->dataLength = 0;
		cu = cu->next;
	}
	cb->UnitCount = 0;
	cb->HasSeenEOS = 0;

	if (cb->odm->mo) cb->odm->mo->timestamp = 0;

	cb->output = cb->input;
	gf_odm_lock(cb->odm, 0);
}
Esempio n. 5
0
/*resize buffers (blocking)*/
void gf_cm_resize(GF_CompositionMemory *cb, u32 newCapacity)
{
	GF_CMUnit *cu;
	if (!newCapacity) return;

	/*lock buffer*/
	gf_odm_lock(cb->odm, 1);
	cu = cb->input;

	cb->UnitSize = newCapacity;
	if (!cb->no_allocation) {
		my_large_gf_free(cu->data);
		cu->data = (char*) my_large_alloc(newCapacity);
	} else {
		cu->data = NULL;
		if (cu->dataLength && cb->odm->raw_frame_sema) {
			cu->dataLength = 0;
			gf_sema_notify(cb->odm->raw_frame_sema, 1);
		}
	}
	cu = cu->next;
	while (cu != cb->input) {
		if (!cb->no_allocation) {
			my_large_gf_free(cu->data);
			cu->data = (char*) my_large_alloc(newCapacity);
		} else {
			cu->data = NULL;
		}
		cu = cu->next;
	}

	gf_odm_lock(cb->odm, 0);
}
Esempio n. 6
0
/*drop the output CU*/
void gf_cm_drop_output(GF_CompositionMemory *cb)
{
	gf_cm_output_kept(cb);

	/*WARNING: in RAW mode, we (for the moment) only have one unit - setting output->dataLength to 0 means the input is available
	for the raw channel - we have to make sure the output is completely reseted before releasing the sema*/

	/*on visual streams (except raw oness), always keep the last AU*/
	if (cb->output->dataLength && (cb->odm->codec->type == GF_STREAM_VISUAL) ) {
		if ( !cb->output->next->dataLength || (cb->Capacity == 1) )  {
			Bool no_drop = 1;
			if (cb->no_allocation ) {
				if (cb->odm->term->bench_mode)
					no_drop = 0;
				else if (gf_clock_time(cb->odm->codec->ck) > cb->output->TS)
					no_drop = 0;
			}
			if (no_drop) {
				if (cb->odm->raw_frame_sema) {
					cb->output->dataLength = 0;
					gf_sema_notify(cb->odm->raw_frame_sema, 1);
				}
				return;
			}
		}
	}

	/*reset the output*/
	cb->output->dataLength = 0;
	if (cb->output->frame) {
		cb->output->frame->Release(cb->output->frame);
		cb->output->frame = NULL;
	}
	cb->output->TS = 0;
	cb->output = cb->output->next;
	cb->UnitCount -= 1;

	if (!cb->HasSeenEOS && cb->UnitCount <= cb->Min) {
		cb->odm->codec->PriorityBoost = 1;
	}

	if (cb->odm->raw_frame_sema) {
		gf_sema_notify(cb->odm->raw_frame_sema, 1);
	}
}
Esempio n. 7
0
DWORD WINAPI RunThread(void *ptr)
{
	DWORD ret = 0;
#else
void * RunThread(void *ptr)
{
	long int ret = 0;
#endif
	GF_Thread *t = (GF_Thread *)ptr;

	/* Signal the caller */
	if (! t->_signal) goto exit;
#ifdef GPAC_ANDROID
	if (pthread_once(&currentThreadInfoKey_once, &currentThreadInfoKey_alloc) || pthread_setspecific(currentThreadInfoKey, t))
		GF_LOG(GF_LOG_ERROR, GF_LOG_MUTEX, ("[Mutex] Couldn't run thread %s, ID 0x%08x\n", t->log_name, t->id));
#endif /* GPAC_ANDROID */
	t->status = GF_THREAD_STATUS_RUN;
	gf_sema_notify(t->_signal, 1);

#ifndef GPAC_DISABLE_LOG
	t->id = gf_th_id();
	GF_LOG(GF_LOG_INFO, GF_LOG_MUTEX, ("[Thread %s] At %d Entering thread proc - thread ID 0x%08x\n", t->log_name, gf_sys_clock(), t->id));
#endif

	/* Each thread has its own seed */
	gf_rand_init(0);

	/* Run our thread */
	ret = t->Run(t->args);

exit:
#ifndef GPAC_DISABLE_LOG
	GF_LOG(GF_LOG_INFO, GF_LOG_MUTEX, ("[Thread %s] At %d Exiting thread proc\n", t->log_name, gf_sys_clock()));
#endif
	t->status = GF_THREAD_STATUS_DEAD;
	t->Run = NULL;
#ifdef WIN32
	if (!CloseHandle(t->threadH)) {
		DWORD err = GetLastError();
		GF_LOG(GF_LOG_ERROR, GF_LOG_MUTEX, ("[Thread %s] Couldn't close handle when exiting thread proc, error code: %d\n", t->log_name, err));
	}
	t->threadH = NULL;
	return ret;
#else

#ifdef GPAC_ANDROID
	#ifndef GPAC_DISABLE_LOG
		GF_LOG(GF_LOG_INFO, GF_LOG_MUTEX, ("[Thread %s] RunBeforeExit=%p\n", t->log_name, t->RunBeforeExit));
	#endif
	if (t->RunBeforeExit)
		t->RunBeforeExit(t->args);
#endif /* GPAC_ANDROID */
	pthread_exit((void *)0);
	return (void *)ret;
#endif
}
Esempio n. 8
0
void dc_producer_end_signal(Producer *producer, CircularBuffer *circular_buf)
{
	Node *node = &circular_buf->list[producer->idx];

	gf_mx_p(node->mutex);
	node->marked = 2;
	gf_sema_notify(node->consumers_semaphore, node->num_consumers_waiting);
	GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("producer %s sends end signal %d \n", producer->name, producer->idx));
	gf_mx_v(node->mutex);
}
Esempio n. 9
0
void dc_producer_end_signal_previous(Producer *producer, CircularBuffer *circular_buf)
{
	int i_node = (producer->max_idx + producer->idx - 1) % producer->max_idx;
	Node *node = &circular_buf->list[i_node];

	gf_mx_p(node->mutex);
	node->marked = 2;
	gf_sema_notify(node->consumers_semaphore, node->num_consumers_waiting);
	GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("producer %s sends end signal %d \n", producer->name, node));
	gf_mx_v(node->mutex);
}
Esempio n. 10
0
void dc_producer_advance(Producer *producer, CircularBuffer *circular_buf)
{
	if (circular_buf->size == 1) {
		Node *node = &circular_buf->list[producer->idx];
		gf_mx_p(node->mutex);
		node->marked = 1;
		gf_sema_notify(node->consumers_semaphore, node->num_consumers_waiting);
		gf_mx_v(node->mutex);
	}
	producer->idx = (producer->idx + 1) % producer->max_idx;
}
Esempio n. 11
0
void dc_producer_unlock_previous(Producer *producer, CircularBuffer *circular_buf)
{
	int node_idx = (producer->idx - 1 + producer->max_idx) % producer->max_idx;
	Node *node = &circular_buf->list[node_idx];

	gf_mx_p(node->mutex);
	node->num_producers = 0;
	gf_sema_notify(node->consumers_semaphore, node->num_consumers_waiting);
	GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("producer %s unlock %d \n", producer->name, node_idx));
	gf_mx_v(node->mutex);
}
Esempio n. 12
0
static JSBool SMJS_FUNCTION(upnp_action_send_reply)
{
	SMJS_OBJ
	SMJS_ARGS
	GPAC_GenericDevice *device = (GPAC_GenericDevice *)SMJS_GET_PRIVATE(c, obj);
	if (!device) return JS_FALSE;

	if (argc && JSVAL_IS_OBJECT(argv[0]) ) {
		JSObject *list = JSVAL_TO_OBJECT(argv[0]);
		u32 i, count;
		JS_GetArrayLength(c, list, (jsuint*) &count);

		GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Calling response %s(", (char *) device->act_ref->GetActionDesc().GetName()));
		i=0;
		while (i+2<=count) {
			jsval an_arg;
			NPT_Result res;
			char *param_val, *_param_val = NULL;
			char szParamVal[1024];
			JS_GetElement(c, list, (jsint) i, &an_arg);
			char *param_name = SMJS_CHARS(c, an_arg);

			JS_GetElement(c, list, (jsint) i+1, &an_arg);

			param_val = (char*)"";
			if (JSVAL_IS_STRING(an_arg)) {
				param_val = _param_val = SMJS_CHARS(c, an_arg);
			} else if (JSVAL_IS_BOOLEAN(an_arg)) {
				param_val = (char *) ((JSVAL_TO_BOOLEAN(an_arg) == JS_TRUE) ? "true" : "false");
			}
			else if (JSVAL_IS_INT(argv[1])) {
				sprintf(szParamVal, "%d",  JSVAL_TO_INT(an_arg));
				param_val = szParamVal;
			}
			else if (JSVAL_IS_NUMBER(an_arg)) {
				jsdouble v;
				JS_ValueToNumber(c, an_arg, &v);
				sprintf(szParamVal, "%g", v);
				param_val = szParamVal;
			}

			if (!param_name || !param_val) res = NPT_FAILURE;
			else {
				GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, (" %s(%s)", param_name, param_val));

				res = device->act_ref->SetArgumentValue(param_name, param_val);
			}
			SMJS_FREE(c, param_name);
			SMJS_FREE(c, _param_val);
			if (res != NPT_SUCCESS) return JS_FALSE;
			i+=2;
		}
		GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, (" )\n"));
	}

	//notify we are ready
	if (device->m_pSema) {
		gf_sema_notify(device->m_pSema, 1);
	}
	return JS_TRUE;
}