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; }
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); } } }
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; }
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; }
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); } } }
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); }