/*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); } }
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; }
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; }
/*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); }
/*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); }
/*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); } }
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(¤tThreadInfoKey_once, ¤tThreadInfoKey_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 }
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); }
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); }
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; }
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); }
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; }