示例#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
NPT_Result
GPAC_GenericDevice::OnAction(PLT_ActionReference&          action,
                             const PLT_HttpRequestContext& context)
{
	NPT_COMPILER_UNUSED(context);

#ifdef GPAC_HAS_SPIDERMONKEY
	gf_mx_p(m_pMutex);
#endif
	PLT_ActionDesc &act_desc = action->GetActionDesc();
	NPT_String name = act_desc.GetName();
#ifdef GPAC_HAS_SPIDERMONKEY
	assert(!m_pSema);
#endif
	GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Action %s called (thread %d)\n", (char *) name, gf_th_id() ));

#ifdef GPAC_HAS_SPIDERMONKEY
	if (JSVAL_IS_NULL(act_proc)) {
		gf_mx_v(m_pMutex);
		return NPT_SUCCESS;
	}

	jsval argv[2];

	m_pUPnP->LockJavascript(GF_TRUE);

	JSObject *js_action = JS_NewObject(m_pUPnP->m_pJSCtx, &m_pUPnP->upnpDeviceClass._class, 0, 0);
	argv[0] = OBJECT_TO_JSVAL(js_action);
	SMJS_SET_PRIVATE(m_pUPnP->m_pJSCtx, js_action, this);

	act_ref = action;

	JS_DefineProperty(m_pUPnP->m_pJSCtx, js_action, "Name", STRING_TO_JSVAL( JS_NewStringCopyZ(m_pUPnP->m_pJSCtx, name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
	GPAC_Service *service = (GPAC_Service *) act_desc.GetService();
	JS_DefineProperty(m_pUPnP->m_pJSCtx, js_action, "Service", service->m_pObj ? OBJECT_TO_JSVAL( service->m_pObj) : JSVAL_NULL, 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_pUPnP->m_pJSCtx, js_action, "GetArgument", upnp_action_get_argument, 1, 0);
	JS_DefineFunction(m_pUPnP->m_pJSCtx, js_action, "SendReply", upnp_action_send_reply, 1, 0);

	/*create a semaphore*/
	m_pSema = gf_sema_new(1, 0);

	jsval rval;
	JS_CallFunctionValue(m_pUPnP->m_pJSCtx, obj, act_proc, 1, argv, &rval);
	SMJS_SET_PRIVATE(m_pUPnP->m_pJSCtx, js_action, NULL);
	m_pUPnP->LockJavascript(GF_FALSE);

	if (JSVAL_IS_INT(rval) && (JSVAL_TO_INT(rval) != 0)) {
		action->SetError(JSVAL_TO_INT(rval), "Action Failed");
	}
	/*wait on the semaphore*/
	if (!gf_sema_wait_for(m_pSema, 10000)) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[UPnP] Reply processing to action %s timeout - sending incomplete reply)\n", (char *) name));
	}
	gf_sema_del(m_pSema);
	m_pSema = NULL;

	gf_mx_v(m_pMutex);
#endif
	return NPT_SUCCESS;
}
示例#3
0
void dc_circular_buffer_create(CircularBuffer *circular_buf, u32 size, LockMode mode, int max_num_consumers)
{
	u32 i;
	circular_buf->size = size;
	circular_buf->list = (Node*)gf_malloc(size * sizeof(Node));
	circular_buf->mode = mode;
	circular_buf->max_num_consumers = max_num_consumers;

	for (i=0; i<size; i++) {
		circular_buf->list[i].num_producers = 0;
		circular_buf->list[i].num_consumers = 0;
		circular_buf->list[i].num_consumers_accessed = 0;
		circular_buf->list[i].marked = 0;
		circular_buf->list[i].num_consumers_waiting = 0;
		circular_buf->list[i].consumers_semaphore = gf_sema_new(1000, 0);
		circular_buf->list[i].producers_semaphore = gf_sema_new(1000, 0);
		circular_buf->list[i].mutex = gf_mx_new("Circular Buffer Mutex");
	}
}
示例#4
0
GF_EXPORT
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) {
#ifdef _MSC_VER
		/*add thread name for the msvc debugger*/
#pragma pack(push,8)
		typedef struct {
			DWORD dwType;
			LPCSTR szName;
			DWORD dwThreadID;
			DWORD dwFlags;
		} THREADNAME_INFO;
#pragma pack(pop)
		THREADNAME_INFO info;
		info.dwType = 0x1000;
		info.szName = t->log_name;
		info.dwThreadID = id;
		info.dwFlags = 0;
		__try {
			RaiseException(0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
		} __except (EXCEPTION_CONTINUE_EXECUTION) {
		}
#endif
	} else {
#else
	if ( pthread_attr_init(&att) != 0 ) return GF_IO_ERR;
示例#5
0
文件: decoder.c 项目: golgol7777/gpac
GF_Err gf_codec_add_channel(GF_Codec *codec, GF_Channel *ch)
{
	GF_Err e;
	GF_NetworkCommand com;
	GF_Channel *a_ch;
	char *dsi;
	u32 dsiSize, CUsize, i;
	GF_CodecCapability cap;
	u32 min, max;


	/*only for valid codecs (eg not OCR)*/
	if (codec->decio) {
		com.get_dsi.dsi = NULL;
		dsi = NULL;
		dsiSize = 0;
		if (ch->esd->decoderConfig->upstream) codec->flags |= GF_ESM_CODEC_HAS_UPSTREAM;
		if (ch->esd->decoderConfig->decoderSpecificInfo) {
			dsi = ch->esd->decoderConfig->decoderSpecificInfo->data;
			dsiSize = ch->esd->decoderConfig->decoderSpecificInfo->dataLength;
		}
		/*For objects declared in OD stream, override with network DSI if any*/
		if (ch->service && !(ch->odm->flags & GF_ODM_NOT_IN_OD_STREAM) ) {
			com.command_type = GF_NET_CHAN_GET_DSI;
			com.base.on_channel = ch;
			e = gf_term_service_command(ch->service, &com);
			if (!e && com.get_dsi.dsi) {
				dsi = com.get_dsi.dsi;
				dsiSize = com.get_dsi.dsi_len;

				if (ch->esd->decoderConfig->decoderSpecificInfo->data) gf_free(ch->esd->decoderConfig->decoderSpecificInfo->data);
				ch->esd->decoderConfig->decoderSpecificInfo->data = com.get_dsi.dsi;
				ch->esd->decoderConfig->decoderSpecificInfo->dataLength = com.get_dsi.dsi_len;
			}
		}
		GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[Codec] Attaching stream %d to codec %s\n", ch->esd->ESID, codec->decio->module_name));

		/*lock the channel before setup in case we are using direct_decode */
		gf_mx_p(ch->mx);
		e = codec->decio->AttachStream(codec->decio, ch->esd);
		gf_mx_v(ch->mx);

		if (ch->esd->decoderConfig && ch->esd->decoderConfig->rvc_config) {
			gf_odf_desc_del((GF_Descriptor *)ch->esd->decoderConfig->rvc_config);
			ch->esd->decoderConfig->rvc_config = NULL;
		}

		if (e) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[Codec] Attach Stream failed %s\n", gf_error_to_string(e) ));
			return e;
		}

		/*ask codec for desired output capacity - note this may be 0 if stream is not yet configured*/
		cap.CapCode = GF_CODEC_OUTPUT_SIZE;
		gf_codec_get_capability(codec, &cap);
		if (codec->CB && (cap.cap.valueInt != codec->CB->UnitSize)) {
			gf_cm_del(codec->CB);
			codec->CB = NULL;
		}
		CUsize = cap.cap.valueInt;

		/*get desired amount of units and minimal fullness (used for scheduling)*/
		switch(codec->type) {
		case GF_STREAM_VISUAL:
		case GF_STREAM_AUDIO:
			cap.CapCode = GF_CODEC_BUFFER_MIN;
			gf_codec_get_capability(codec, &cap);
			min = cap.cap.valueInt;
			cap.CapCode = GF_CODEC_BUFFER_MAX;
			gf_codec_get_capability(codec, &cap);
			max = cap.cap.valueInt;
			break;
		case GF_STREAM_ND_SUBPIC:
			max = 1;
			min = 0;
			break;
		default:
			min = max = 0;
		}
		if ((codec->type==GF_STREAM_AUDIO) && (max<2)) max = 2;

		/*setup CB*/
		if (!codec->CB && max) {
			if (codec->flags & GF_ESM_CODEC_IS_RAW_MEDIA) {
				max = 1;
				/*create a semaphore in non-notified stage*/
				codec->odm->raw_frame_sema = gf_sema_new(1, 0);
			}

			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[ODM] Creating composition buffer for codec %s - %d units %d bytes each\n", codec->decio->module_name, max, CUsize));

			codec->CB = gf_cm_new(CUsize, max, (codec->flags & GF_ESM_CODEC_IS_RAW_MEDIA) ? 1 : 0);
			codec->CB->Min = min;
			codec->CB->odm = codec->odm;
		}

		if (codec->CB) {
			/*check re-ordering - set by default on all codecs*/
			codec->is_reordering = 1;
			cap.CapCode = GF_CODEC_REORDER;
			if (gf_codec_get_capability(codec, &cap) == GF_OK)
				codec->is_reordering = cap.cap.valueInt;
		}

		if (codec->flags & GF_ESM_CODEC_IS_RAW_MEDIA) {
			ch->is_raw_channel = 1;
		}

		/*setup net channel config*/
		if (ch->service) {
			memset(&com, 0, sizeof(GF_NetworkCommand));
			com.command_type = GF_NET_CHAN_CONFIG;
			com.base.on_channel = ch;

			com.cfg.priority = ch->esd->streamPriority;
			com.cfg.sync_id = ch->clock->clockID;
			memcpy(&com.cfg.sl_config, ch->esd->slConfig, sizeof(GF_SLConfig));
			/*get the frame duration if audio (used by some network stack)*/
			if (ch->odm->codec && (ch->odm->codec->type==GF_STREAM_AUDIO) ) {
				cap.CapCode = GF_CODEC_SAMPLERATE;
				gf_codec_get_capability(ch->odm->codec, &cap);
				com.cfg.sample_rate = cap.cap.valueInt;
				cap.CapCode = GF_CODEC_CU_DURATION;
				gf_codec_get_capability(ch->odm->codec, &cap);
				com.cfg.frame_duration = cap.cap.valueInt;
			}
			gf_term_service_command(ch->service, &com);

			ch->carousel_type = GF_ESM_CAROUSEL_NONE;
			if (com.cfg.use_m2ts_sections) {
				ch->carousel_type = GF_ESM_CAROUSEL_MPEG2;
			} else {
				switch (ch->esd->decoderConfig->streamType) {
				case GF_STREAM_OD:
				case GF_STREAM_SCENE:
					ch->carousel_type = ch->esd->slConfig->AUSeqNumLength ? GF_ESM_CAROUSEL_MPEG4 : GF_ESM_CAROUSEL_NONE;
					break;
				}
			}
		
		}
	}

	/*assign the first base layer as the codec clock by default, or current channel clock if no clock set
	Also assign codec priority here*/
	if (!ch->esd->dependsOnESID || !codec->ck) {
		codec->ck = ch->clock;
		codec->Priority = ch->esd->streamPriority;
		/*insert base layer first - note we are sure this is a stream of the same type
		as the codec (other streams - OCI, MPEG7, MPEGJ - are not added that way)*/
		return gf_list_insert(codec->inChannels, ch, 0);
	}
	else {
		/*make sure all channels are in order*/
		i=0;
		while ((a_ch = (GF_Channel*)gf_list_enum(codec->inChannels, &i))) {
			if (ch->esd->dependsOnESID == a_ch->esd->ESID) {
				return gf_list_insert(codec->inChannels, ch, i);
			}
			if (a_ch->esd->dependsOnESID == ch->esd->ESID) {
				return gf_list_insert(codec->inChannels, ch, i-1);
			}
		}
		/*by default append*/
		return gf_list_add(codec->inChannels, ch);
	}
}
示例#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);
}