BRCMIMAGE_STATUS_T brcmimage_create(BRCMIMAGE_TYPE_T type, unsigned int encoding, BRCMIMAGE_T **ctx) { BRCMIMAGE_STATUS_T status = BRCMIMAGE_SUCCESS; BRCMIMAGE_T **comp; if (type == BRCMIMAGE_TYPE_ENCODER) comp = &brcmimage_encoder[getEncoderIndexFromType(encoding)]; else comp = &brcmimage_decoder[getEncoderIndexFromType(encoding)]; vcos_once(&once, brcmimage_init_once); LOCK(); if (!*comp) { int init1, init2, init3; *comp = (BRCMIMAGE_T*)calloc(sizeof(BRCMIMAGE_T), 1); if (!*comp) { UNLOCK(); return BRCMIMAGE_ERROR_NOMEM; } (*comp)->type = type; (*comp)->encoding = encoding; init1 = vcos_mutex_create(&(*comp)->lock, "brcmimage lock") != VCOS_SUCCESS; init2 = vcos_mutex_create(&(*comp)->process_lock, "brcmimage process lock") != VCOS_SUCCESS; init3 = vcos_semaphore_create(&(*comp)->sema, "brcmimage sema", 0) != VCOS_SUCCESS; if (init1 | init2 | init3) { if (init1) vcos_mutex_delete(&(*comp)->lock); if (init2) vcos_mutex_delete(&(*comp)->process_lock); if (init3) vcos_semaphore_delete(&(*comp)->sema); free(comp); UNLOCK(); return BRCMIMAGE_ERROR_NOMEM; } } (*comp)->ref_count++; UNLOCK(); LOCK_COMP(*comp); if (!(*comp)->init) { if (type == BRCMIMAGE_TYPE_ENCODER) status = brcmimage_init_encoder(*comp); else status = brcmimage_init_decoder(*comp); (*comp)->init = status == BRCMIMAGE_SUCCESS; } UNLOCK_COMP(*comp); if (status != BRCMIMAGE_SUCCESS) brcmimage_release(*comp); *ctx = *comp; return status; }
BRCMJPEG_STATUS_T brcmjpeg_create(BRCMJPEG_TYPE_T type, BRCMJPEG_T **ctx) { BRCMJPEG_STATUS_T status = BRCMJPEG_SUCCESS; BRCMJPEG_T **comp; if (type == BRCMJPEG_TYPE_ENCODER) comp = &brcmjpeg_encoder; else comp = &brcmjpeg_decoder; vcos_once(&once, brcmjpeg_init_once); LOCK(); if (!*comp) { int init1, init2, init3; *comp = (BRCMJPEG_T*)calloc(sizeof(BRCMJPEG_T), 1); if (!*comp) { UNLOCK(); return BRCMJPEG_ERROR_NOMEM; } (*comp)->type = type; init1 = vcos_mutex_create(&(*comp)->lock, "brcmjpeg lock") != VCOS_SUCCESS; init2 = vcos_mutex_create(&(*comp)->process_lock, "brcmjpeg process lock") != VCOS_SUCCESS; init3 = vcos_semaphore_create(&(*comp)->sema, "brcmjpeg sema", 0) != VCOS_SUCCESS; if (init1 | init2 | init3) { if (init1) vcos_mutex_delete(&(*comp)->lock); if (init2) vcos_mutex_delete(&(*comp)->process_lock); if (init3) vcos_semaphore_delete(&(*comp)->sema); free(comp); UNLOCK(); return BRCMJPEG_ERROR_NOMEM; } } (*comp)->ref_count++; UNLOCK(); LOCK_COMP(*comp); if (!(*comp)->init) { if (type == BRCMJPEG_TYPE_ENCODER) status = brcmjpeg_init_encoder(*comp); else status = brcmjpeg_init_decoder(*comp); (*comp)->init = status == BRCMJPEG_SUCCESS; } UNLOCK_COMP(*comp); if (status != BRCMJPEG_SUCCESS) brcmjpeg_release(*comp); *ctx = *comp; return status; }
VCOS_STATUS_T vcos_init(void) { VCOS_STATUS_T st = VCOS_SUCCESS; #ifdef HAVE_MTRACE // enable glibc memory debugging, if the environment // variable MALLOC_TRACE names a valid file. mtrace(); #endif vcos_mutex_create(&lock, "global_lock"); vcos_demand(pthread_key_create(&_vcos_thread_current_key, NULL) == 0); /* Initialise a VCOS wrapper for the thread which called vcos_init. */ vcos_semaphore_create(&vcos_thread_main.suspend, NULL, 0); vcos_thread_main.thread = pthread_self(); pthread_setspecific(_vcos_thread_current_key, &vcos_thread_main); st = vcos_msgq_init(); vcos_assert(st == VCOS_SUCCESS); vcos_logging_init(); return st; }
/** Create a QUEUE of MMAL_BUFFER_HEADER_T */ MMAL_QUEUE_T *mmal_queue_create(void) { MMAL_QUEUE_T *queue; queue = vcos_malloc(sizeof(*queue), "MMAL queue"); if(!queue) return 0; if(vcos_mutex_create(&queue->lock, "MMAL queue lock") != VCOS_SUCCESS ) { vcos_free(queue); return 0; } if(vcos_semaphore_create(&queue->semaphore, "MMAL queue sema", 0) != VCOS_SUCCESS ) { vcos_mutex_delete(&queue->lock); vcos_free(queue); return 0; } /* gratuitous lock for coverity */ vcos_mutex_lock(&queue->lock); queue->length = 0; queue->first = 0; queue->last = &queue->first; mmal_queue_sanity_check(queue, NULL); /* gratuitous unlock for coverity */ vcos_mutex_unlock(&queue->lock); return queue; }
static void brcmimage_init_once(void) { vcos_mutex_create(&brcmimage_lock, VCOS_FUNCTION); for (int i=0; i < MAX_ENCODER_TYPES; i++) { brcmimage_encoder[i] = NULL; brcmimage_decoder[i] = NULL; } }
/** Create a new vidtex instance */ static VIDTEX_T *vidtex_create(EGLNativeWindowType win) { VIDTEX_T *vt; VCOS_STATUS_T st; vt = vcos_calloc(1, sizeof(*vt), "vidtex"); if (vt == NULL) { vcos_log_trace("Memory allocation failure"); return NULL; } st = vcos_semaphore_create(&vt->sem_decoded, "vidtex-dec", 0); if (st != VCOS_SUCCESS) { vcos_log_trace("Error creating semaphore"); goto error_ctx; } st = vcos_semaphore_create(&vt->sem_drawn, "vidtex-drw", 0); if (st != VCOS_SUCCESS) { vcos_log_trace("Error creating semaphore"); goto error_sem1; } st = vcos_mutex_create(&vt->mutex, "vidtex"); if (st != VCOS_SUCCESS) { vcos_log_trace("Error creating semaphore"); goto error_sem2; } if (vidtex_gl_init(vt, win) != 0) { vcos_log_trace("Error initialising EGL"); goto error_mutex; } vt->quit = false; vt->stop_reason = 0; return vt; error_mutex: vcos_mutex_delete(&vt->mutex); error_sem2: vcos_semaphore_delete(&vt->sem_drawn); error_sem1: vcos_semaphore_delete(&vt->sem_decoded); error_ctx: vcos_free(vt); return NULL; }
static VCOS_STATUS_T vcos_msgq_create(VCOS_MSGQUEUE_T *q) { VCOS_STATUS_T st; memset(q, 0, sizeof(*q)); st = vcos_semaphore_create(&q->sem,"vcos:msgqueue",0); if (st == VCOS_SUCCESS) st = vcos_mutex_create(&q->lock,"vcos:msgqueue"); return st; }
VCOS_STATUS_T vcos_generic_event_flags_create(VCOS_EVENT_FLAGS_T *flags, const char *name) { VCOS_STATUS_T rc; if ((rc=vcos_mutex_create(&flags->lock, name)) != VCOS_SUCCESS) { return rc; } flags->events = 0; flags->waiters.head = flags->waiters.tail = 0; return rc; }
void vcos_logging_init(void) { if (inited) { // FIXME: should print a warning or something here return; } vcos_mutex_create(&lock, "vcos_log"); vcos_log_register("default", &dflt_log_category); dflt_log_category.flags.want_prefix = 0; vcos_assert(!inited); inited = 1; }
void vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_CHANNEL_T *local, VCHIQ_CHANNEL_T *remote) { VCOS_THREAD_ATTR_T attrs; char threadname[8]; static int id = 0; vcos_assert(is_pow2(VCHIQ_CHANNEL_SIZE)); vcos_assert(is_pow2(VCHIQ_NUM_CURRENT_BULKS)); vcos_assert(is_pow2(VCHIQ_NUM_SERVICE_BULKS)); vcos_assert(sizeof(VCHIQ_HEADER_T) == 8); /* we require this for consistency between endpoints */ memset(state, 0, sizeof(VCHIQ_STATE_T)); state->id = id++; /* initialize events and mutex */ vcos_event_create(&state->connect, "vchiq"); vcos_mutex_create(&state->mutex, "vchiq"); /* initialize channel pointers */ state->local = local; state->remote = remote; vchiq_init_channel(local); /* bring up slot handler thread */ vcos_thread_attr_init(&attrs); vcos_thread_attr_setstacksize(&attrs, VCHIQ_SLOT_HANDLER_STACK); vcos_thread_attr_setpriority(&attrs, 5); /* FIXME: should not be hardcoded */ vcos_thread_attr_settimeslice(&attrs, 20); /* FIXME: should not be hardcoded */ strcpy(threadname, "VCHIQ-0"); threadname[6] += state->id % 10; vcos_thread_create(&state->slot_handler_thread, threadname, &attrs, slot_handler_func, state); /* Indicate readiness to the other side */ local->initialised = 1; }
VCOS_STATUS_T vcos_msgq_init(void) { VCOS_STATUS_T st = vcos_mutex_create(&lock,"msgq"); if (st != VCOS_SUCCESS) goto fail_mtx; st = vcos_tls_create(&tls_key); if (st != VCOS_SUCCESS) goto fail_tls; endpoints = NULL; return st; fail_tls: vcos_mutex_delete(&lock); fail_mtx: return st; }
CComponent::CComponent(std::string sName, CGraph* pGraph) : m_sName(std::move(sName)), m_hComponent(NULL), m_pGraph(pGraph) { std::string sStateChangedEventName(m_sName); sStateChangedEventName.append(":state_changed_event"); CHECK_VCOS(vcos_event_create(&m_StateChangedEvent, sStateChangedEventName.c_str()), "failed to create vcos event"); std::string sEventThreadName(m_sName); sEventThreadName.append(":event_thread"); m_EventThread.Start(&CComponent::EventThreadProc, this, sEventThreadName.c_str()); std::string sEventQueueMutexName(m_sName); sEventQueueMutexName.append(":event_queue_mutex"); vcos_mutex_create(&m_EventQueueMutex, sEventThreadName.c_str()); OMX_CALLBACKTYPE Callbacks; Callbacks.EventHandler = &CComponent::EventHandler; Callbacks.EmptyBufferDone = &CComponent::EmptyBufferDone; Callbacks.FillBufferDone = &CComponent::FillBufferDone; std::string sError("failed to create component "); sError.append(m_sName); CHECK_OMX(OMX_GetHandle(&m_hComponent, const_cast<char*>(m_sName.c_str()), this, &Callbacks), sError.c_str()); }
void vcos_logging_init(void) { if (inited) { /* FIXME: should print a warning or something here */ return; } vcos_mutex_create(&lock, "vcos_log"); vcos_log_platform_init(); vcos_log_register("default", &dflt_log_category); #if VCOS_WANT_LOG_CMD vcos_cmd_register( &cmd_log ); #endif vcos_assert(!inited); inited = 1; }
void vc_vchi_gencmd_init (VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ) { VCOS_STATUS_T status; int32_t success; int i; if (gencmd_client.initialised) return; // record the number of connections memset( &gencmd_client, 0, sizeof(GENCMD_SERVICE_T) ); gencmd_client.num_connections = (int) num_connections; status = vcos_mutex_create(&gencmd_client.lock, "HGencmd"); vcos_assert(status == VCOS_SUCCESS); status = vcos_event_create(&gencmd_client.message_available_event, "HGencmd"); vcos_assert(status == VCOS_SUCCESS); for (i=0; i<gencmd_client.num_connections; i++) { // Create a 'LONG' service on the each of the connections SERVICE_CREATION_T gencmd_parameters = { VCHI_VERSION(VC_GENCMD_VER), MAKE_FOURCC("GCMD"), // 4cc service code connections[i], // passed in fn ptrs 0, // tx fifo size (unused) 0, // tx fifo size (unused) &gencmd_callback, // service callback &gencmd_client.message_available_event, // callback parameter VC_FALSE, // want_unaligned_bulk_rx VC_FALSE, // want_unaligned_bulk_tx VC_FALSE // want_crc }; success = vchi_service_open( initialise_instance, &gencmd_parameters, &gencmd_client.open_handle[i] ); assert( success == 0 ); } gencmd_client.initialised = 1; release_gencmd_service(); }
static void init_once(void) { vcos_mutex_create(&gpuserv_client.lock, VCOS_FUNCTION); }
VCOS_STATUS_T vcos_generic_reentrant_mutex_create(VCOS_REENTRANT_MUTEX_T *m, const char *name) { m->count = 0; m->owner = 0; return vcos_mutex_create(&m->mutex, name); }
VCOS_STATUS_T vcos_generic_blockpool_init(VCOS_BLOCKPOOL_T *pool, VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size, void *start, VCOS_UNSIGNED pool_size, VCOS_UNSIGNED align, VCOS_UNSIGNED flags, const char *name) { VCOS_STATUS_T status = VCOS_SUCCESS; vcos_unused(name); vcos_unused(flags); vcos_log_trace( "%s: pool %p num_blocks %d block_size %d start %p pool_size %d name %p", VCOS_FUNCTION, pool, num_blocks, block_size, start, pool_size, name); vcos_demand(pool); vcos_demand(start); vcos_assert((block_size > 0)); vcos_assert(num_blocks > 0); if (! align) align = VCOS_BLOCKPOOL_ALIGN_DEFAULT; if (align & 0x3) { vcos_log_error("%s: invalid alignment %d", VCOS_FUNCTION, align); return VCOS_EINVAL; } if (VCOS_BLOCKPOOL_SIZE(num_blocks, block_size, align) > pool_size) { vcos_log_error("%s: Pool is too small" \ " num_blocks %d block_size %d align %d" " pool_size %d required size %d", VCOS_FUNCTION, num_blocks, block_size, align, pool_size, (int) VCOS_BLOCKPOOL_SIZE(num_blocks, block_size, align)); return VCOS_ENOMEM; } status = vcos_mutex_create(&pool->mutex, "vcos blockpool mutex"); if (status != VCOS_SUCCESS) return status; pool->block_data_size = block_size; /* TODO - create flag that if set forces the header to be in its own cache * line */ pool->block_size = VCOS_BLOCKPOOL_ROUND_UP(pool->block_data_size + (align >= 4096 ? 32 : 0) + sizeof(VCOS_BLOCKPOOL_HEADER_T), align); pool->magic = VCOS_BLOCKPOOL_MAGIC; pool->num_subpools = 1; pool->num_extension_blocks = 0; pool->align = align; memset(pool->subpools, 0, sizeof(pool->subpools)); vcos_generic_blockpool_subpool_init(pool, &pool->subpools[0], start, pool_size, num_blocks, align, VCOS_BLOCKPOOL_SUBPOOL_FLAG_NONE); return status; }
void os_cond_init(void) { vcos_assert(vcos_cv_inited++ == 0); vcos_demand(vcos_mutex_create(&cond_latch,NULL) == VCOS_SUCCESS); }
static void mmal_vc_payload_list_init() { vcos_mutex_create(&mmal_vc_payload_list.lock, "mmal_vc_payload_list"); }
/** Allocate a port structure */ MMAL_PORT_T *mmal_port_alloc(MMAL_COMPONENT_T *component, MMAL_PORT_TYPE_T type, unsigned int extra_size) { MMAL_PORT_T *port; MMAL_PORT_PRIVATE_CORE_T *core; unsigned int name_size = strlen(component->name) + sizeof(PORT_NAME_FORMAT); unsigned int size = sizeof(*port) + sizeof(MMAL_PORT_PRIVATE_T) + sizeof(MMAL_PORT_PRIVATE_CORE_T) + name_size + extra_size; MMAL_BOOL_T lock = 0, lock_send = 0, lock_transit = 0, sema_transit = 0; MMAL_BOOL_T lock_stats = 0, lock_connection = 0; LOG_TRACE("component:%s type:%u extra:%u", component->name, type, extra_size); port = vcos_calloc(1, size, "mmal port"); if (!port) { LOG_ERROR("failed to allocate port, size %u", size); return 0; } port->type = type; port->priv = (MMAL_PORT_PRIVATE_T *)(port+1); port->priv->core = core = (MMAL_PORT_PRIVATE_CORE_T *)(port->priv+1); if (extra_size) port->priv->module = (struct MMAL_PORT_MODULE_T *)(port->priv->core+1); port->component = component; port->name = core->name = ((char *)(port->priv->core+1)) + extra_size; core->name_size = name_size; mmal_port_name_update(port); core->queue_last = &core->queue_first; port->priv->pf_connect = mmal_port_connect_default; lock = vcos_mutex_create(&port->priv->core->lock, "mmal port lock") == VCOS_SUCCESS; lock_send = vcos_mutex_create(&port->priv->core->send_lock, "mmal port send lock") == VCOS_SUCCESS; lock_transit = vcos_mutex_create(&port->priv->core->transit_lock, "mmal port transit lock") == VCOS_SUCCESS; sema_transit = vcos_semaphore_create(&port->priv->core->transit_sema, "mmal port transit sema", 1) == VCOS_SUCCESS; lock_stats = vcos_mutex_create(&port->priv->core->stats_lock, "mmal stats lock") == VCOS_SUCCESS; lock_connection = vcos_mutex_create(&port->priv->core->connection_lock, "mmal connection lock") == VCOS_SUCCESS; if (!lock || !lock_send || !lock_transit || !sema_transit || !lock_stats || !lock_connection) { LOG_ERROR("%s: failed to create sync objects (%u,%u,%u,%u,%u,%u)", port->name, lock, lock_send, lock_transit, sema_transit, lock_stats, lock_connection); goto error; } port->format = mmal_format_alloc(); if (!port->format) { LOG_ERROR("%s: failed to allocate format object", port->name); goto error; } port->priv->core->format_ptr_copy = port->format; LOG_TRACE("%s: created at %p", port->name, port); return port; error: if (lock) vcos_mutex_delete(&port->priv->core->lock); if (lock_send) vcos_mutex_delete(&port->priv->core->send_lock); if (lock_transit) vcos_mutex_delete(&port->priv->core->transit_lock); if (sema_transit) vcos_semaphore_delete(&port->priv->core->transit_sema); if (lock_stats) vcos_mutex_delete(&port->priv->core->stats_lock); if (lock_connection) vcos_mutex_delete(&port->priv->core->connection_lock); if (port->format) mmal_format_free(port->format); vcos_free(port); return 0; }
VCOS_STATUS_T _vcos_named_semaphore_init(void) { memset(sems,0,sizeof(sems)); return vcos_mutex_create(&lock,"vcosnmsem"); }
/* Create Simple Video Player instance. */ SVP_T *svp_create(const char *uri, SVP_CALLBACKS_T *callbacks, const SVP_OPTS_T *opts) { SVP_T *svp; MMAL_STATUS_T st; VCOS_STATUS_T vst; MMAL_PORT_T *reader_output = NULL; MMAL_COMPONENT_T *video_decode = NULL; MMAL_PORT_T *video_output = NULL; LOG_TRACE("Creating player for %s", (uri ? uri : "camera preview")); vcos_assert(callbacks->video_frame_cb); vcos_assert(callbacks->stop_cb); svp = vcos_calloc(1, sizeof(*svp), "svp"); CHECK_STATUS((svp ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to allocate context"); svp->opts = *opts; svp->callbacks = *callbacks; /* Semaphore used for synchronising buffer handling for decoded frames */ vst = vcos_semaphore_create(&svp->sema, "svp-sem", 0); CHECK_STATUS((vst == VCOS_SUCCESS ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to create semaphore"); svp->created |= SVP_CREATED_SEM; vst = vcos_mutex_create(&svp->mutex, "svp-mutex"); CHECK_STATUS((vst == VCOS_SUCCESS ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to create mutex"); svp->created |= SVP_CREATED_MUTEX; vst = vcos_timer_create(&svp->timer, "svp-timer", svp_timer_cb, svp); CHECK_STATUS((vst == VCOS_SUCCESS ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to create timer"); svp->created |= SVP_CREATED_TIMER; vst = vcos_timer_create(&svp->wd_timer, "svp-wd-timer", svp_watchdog_cb, svp); CHECK_STATUS((vst == VCOS_SUCCESS ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to create timer"); svp->created |= SVP_CREATED_WD_TIMER; /* Create components */ svp->reader = NULL; svp->video_decode = NULL; svp->camera = NULL; svp->connection = NULL; if (uri) { /* Video from URI: setup container_reader -> video_decode */ /* Create and set up container reader */ st = mmal_component_create(MMAL_COMPONENT_DEFAULT_CONTAINER_READER, &svp->reader); CHECK_STATUS(st, "Failed to create container reader"); st = svp_setup_reader(svp->reader, uri, &reader_output); if (st != MMAL_SUCCESS) goto error; st = mmal_component_enable(svp->reader); CHECK_STATUS(st, "Failed to enable container reader"); st = svp_port_enable(svp, svp->reader->control, svp_bh_control_cb); CHECK_STATUS(st, "Failed to enable container reader control port"); /* Create and set up video decoder */ st = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &svp->video_decode); CHECK_STATUS(st, "Failed to create video decoder"); video_decode = svp->video_decode; video_output = video_decode->output[0]; st = mmal_component_enable(video_decode); CHECK_STATUS(st, "Failed to enable video decoder"); st = svp_port_enable(svp, video_decode->control, svp_bh_control_cb); CHECK_STATUS(st, "Failed to enable video decoder control port"); } else { /* Camera preview */ MMAL_PARAMETER_CAMERA_CONFIG_T config; st = mmal_component_create(MMAL_COMPONENT_DEFAULT_CAMERA, &svp->camera); CHECK_STATUS(st, "Failed to create camera"); st = mmal_component_enable(svp->camera); CHECK_STATUS(st, "Failed to enable camera"); st = svp_port_enable(svp, svp->camera->control, svp_bh_control_cb); CHECK_STATUS(st, "Failed to enable camera control port"); video_output = svp->camera->output[0]; /* Preview port */ } st = mmal_port_parameter_set_boolean(video_output, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE); CHECK_STATUS((st == MMAL_ENOSYS ? MMAL_SUCCESS : st), "Failed to enable zero copy"); if (uri) { /* Create connection: container_reader -> video_decoder */ st = mmal_connection_create(&svp->connection, reader_output, video_decode->input[0], MMAL_CONNECTION_FLAG_TUNNELLING); CHECK_STATUS(st, "Failed to create connection"); } /* Set video output port format. * Opaque encoding ensures we get buffer data as handles to relocatable heap. */ video_output->format->encoding = MMAL_ENCODING_OPAQUE; if (!uri) { /* Set video format for camera preview */ MMAL_VIDEO_FORMAT_T *vfmt = &video_output->format->es->video; CHECK_STATUS((video_output->format->type == MMAL_ES_TYPE_VIDEO) ? MMAL_SUCCESS : MMAL_EINVAL, "Output port isn't video format"); vfmt->width = SVP_CAMERA_WIDTH; vfmt->height = SVP_CAMERA_HEIGHT; vfmt->crop.x = 0; vfmt->crop.y = 0; vfmt->crop.width = vfmt->width; vfmt->crop.height = vfmt->height; vfmt->frame_rate.num = SVP_CAMERA_FRAMERATE; vfmt->frame_rate.den = 1; } st = mmal_port_format_commit(video_output); CHECK_STATUS(st, "Failed to set output port format"); /* Finally, set buffer num/size. N.B. For container_reader/video_decode, must be after * connection created, in order for port format to propagate. * Don't enable video output port until want to produce frames. */ video_output->buffer_num = video_output->buffer_num_recommended; video_output->buffer_size = video_output->buffer_size_recommended; /* Pool + queue to hold decoded video frames */ svp->out_pool = mmal_port_pool_create(video_output, video_output->buffer_num, video_output->buffer_size); CHECK_STATUS((svp->out_pool ? MMAL_SUCCESS : MMAL_ENOMEM), "Error allocating pool"); svp->queue = mmal_queue_create(); CHECK_STATUS((svp ? MMAL_SUCCESS : MMAL_ENOMEM), "Error allocating queue"); svp->video_output = video_output; return svp; error: svp_destroy(svp); return NULL; }
int main(int argc, const char **argv) { VCOS_THREAD_ATTR_T attrs; int i; vcos_init(); signal(SIGINT, test_signal_handler); /* coverity[tainted_data] Ignore unnecessary warning about an attacker * being able to pass an arbitrarily long "-vvvvv..." argument */ if (test_parse_cmdline(argc, argv)) return -1; if (verbosity--) { static char value[512]; const char *levels[] = {"warn", "info", "trace"}; char *env = getenv("VC_LOGLEVEL"); if (verbosity >= MMAL_COUNTOF(levels)) verbosity = MMAL_COUNTOF(levels) - 1; snprintf(value, sizeof(value)-1, "mmalplay:%s,mmal:%s,%s", levels[verbosity], levels[verbosity], env ? env : ""); #ifdef WIN32 _putenv("VC_LOGLEVEL", value, 1); #else setenv("VC_LOGLEVEL", value, 1); #endif } vcos_log_register("mmalplay", VCOS_LOG_CATEGORY); LOG_INFO("MMAL Video Playback Test App"); vcos_thread_attr_init(&attrs); for (i = 0; i < play_info_count; i++) { const char *uri = play_info[i].uri; memcpy(play_info[i].name, THREAD_PREFIX, sizeof(THREAD_PREFIX)); if (strlen(uri) >= URI_FOR_THREAD_NAME_MAX) uri += strlen(uri) - URI_FOR_THREAD_NAME_MAX; strncat(play_info[i].name, uri, URI_FOR_THREAD_NAME_MAX); vcos_mutex_create(&play_info[i].lock, "mmalplay"); play_info[i].options.render_layer = i; if (vcos_thread_create(&play_info[i].thread, play_info[i].name, &attrs, mmal_playback, &play_info[i]) != VCOS_SUCCESS) { LOG_ERROR("Thread creation failure for URI %s", play_info[i].uri); return -2; } } if (sleepy_time != 0) { #ifdef WIN32 Sleep(sleepy_time); #else sleep(sleepy_time); #endif for (i = 0; i < play_info_count; i++) { vcos_mutex_lock(&play_info[i].lock); if (play_info[i].ctx) mmalplay_stop(play_info[i].ctx); vcos_mutex_unlock(&play_info[i].lock); } } LOG_TRACE("Waiting for threads to terminate"); for (i = 0; i < play_info_count; i++) { vcos_thread_join(&play_info[i].thread, NULL); LOG_TRACE("Joined thread %d (%i)", i, play_info[i].status); } LOG_TRACE("Completed"); /* Check for errors */ for (i = 0; i < play_info_count; i++) { if (!play_info[i].status) continue; LOG_ERROR("Playback of %s failed (%i, %s)", play_info[i].uri, play_info[i].status, mmal_status_to_string(play_info[i].status)); fprintf(stderr, "playback of %s failed (%i, %s)\n", play_info[i].uri, play_info[i].status, mmal_status_to_string(play_info[i].status)); return play_info[i].status; } return 0; }
static void brcmjpeg_init_once(void) { vcos_mutex_create(&brcmjpeg_lock, VCOS_FUNCTION); }
VCOS_STATUS_T vcos_platform_init(void) { VCOS_STATUS_T st; uint32_t flags = 0; int pst; st = _vcos_named_semaphore_init(); if (!vcos_verify(st == VCOS_SUCCESS)) goto end; flags |= VCOS_INIT_NAMED_SEM; #ifdef HAVE_MTRACE /* enable glibc memory debugging, if the environment * variable MALLOC_TRACE names a valid file. */ mtrace(); #endif #ifdef ANDROID st = vcos_mutex_create(&printf_lock, "printf"); if (!vcos_verify(st == VCOS_SUCCESS)) goto end; flags |= VCOS_INIT_PRINTF_LOCK; #endif st = vcos_once(¤t_thread_key_once, current_thread_key_init); if (!vcos_verify(st == VCOS_SUCCESS)) goto end; /* Initialise a VCOS wrapper for the thread which called vcos_init. */ st = vcos_semaphore_create(&vcos_thread_main.suspend, NULL, 0); if (!vcos_verify(st == VCOS_SUCCESS)) goto end; flags |= VCOS_INIT_MAIN_SEM; vcos_thread_main.thread = pthread_self(); pst = pthread_setspecific(_vcos_thread_current_key, &vcos_thread_main); if (!vcos_verify(pst == 0)) { st = VCOS_EINVAL; goto end; } st = vcos_msgq_init(); if (!vcos_verify(st == VCOS_SUCCESS)) goto end; flags |= VCOS_INIT_MSGQ; vcos_logging_init(); end: if (st != VCOS_SUCCESS) vcos_term(flags); return st; }
static void __inline local_mutex_create(LOCAL_MUTEX_T *mutex) { vcos_mutex_create(&mutex->mutex, "vchiq"); }
/* Atomic creation of lock protecting shared state */ static void initOnce(void) { VCOS_STATUS_T status; status = vcos_mutex_create(&lock, VCOS_FUNCTION); vcos_demand(status == VCOS_SUCCESS); }
void vc_vchi_dispmanx_init (VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ) { VCOS_STATUS_T status; int32_t success; uint32_t i; // record the number of connections memset( &dispmanx_client, 0, sizeof(DISPMANX_SERVICE_T) ); dispmanx_client.num_connections = num_connections; status = vcos_mutex_create(&dispmanx_client.lock, "HDispmanx"); vcos_assert(status == VCOS_SUCCESS); status = vcos_event_create(&dispmanx_message_available_event, "HDispmanx"); vcos_assert(status == VCOS_SUCCESS); status = vcos_event_create(&dispmanx_notify_available_event, "HDispmanx"); vcos_assert(status == VCOS_SUCCESS); dispmanx_client.initialised = 1; for (i=0; i<dispmanx_client.num_connections; i++) { VCOS_THREAD_ATTR_T attrs; // Create a 'Client' service on the each of the connections SERVICE_CREATION_T dispmanx_parameters = { DISPMANX_CLIENT_NAME, // 4cc service code connections[i], // passed in fn ptrs 0, // tx fifo size (unused) 0, // tx fifo size (unused) &dispmanx_client_callback, // service callback &dispmanx_message_available_event, // callback parameter VC_FALSE, // want_unaligned_bulk_rx VC_FALSE, // want_unaligned_bulk_tx VC_FALSE, // want_crc }; SERVICE_CREATION_T dispmanx_parameters2 = { DISPMANX_NOTIFY_NAME, // 4cc service code connections[i], // passed in fn ptrs 0, // tx fifo size (unused) 0, // tx fifo size (unused) &dispmanx_notify_callback, // service callback &dispmanx_notify_available_event, // callback parameter VC_FALSE, // want_unaligned_bulk_rx VC_FALSE, // want_unaligned_bulk_tx VC_FALSE, // want_crc }; success = vchi_service_open( initialise_instance, &dispmanx_parameters, &dispmanx_client.client_handle[i] ); vcos_assert( success == 0 ); // Create the async service of dispman to handle update callback success = vchi_service_open( initialise_instance, &dispmanx_parameters2, &dispmanx_client.notify_handle[i] ); vcos_assert( success == 0 ); //Create the notifier task vcos_thread_attr_init(&attrs); vcos_thread_attr_setstacksize(&attrs, 2048); vcos_thread_attr_settimeslice(&attrs, 1); status = vcos_thread_create(&dispmanx_notify_task, "HDispmanx Notify", &attrs, dispmanx_notify_func, NULL); vcos_assert(status == VCOS_SUCCESS); // release services until they're actually used vchi_service_release(dispmanx_client.client_handle[i]); vchi_service_release(dispmanx_client.notify_handle[i]); } }
MMAL_STATUS_T mmal_vc_init(void) { VCHIQ_SERVICE_PARAMS_T vchiq_params; MMAL_BOOL_T vchiq_initialised = 0, waitpool_initialised = 0; MMAL_BOOL_T service_initialised = 0; MMAL_STATUS_T status = MMAL_EIO; VCHIQ_STATUS_T vchiq_status; int count; vcos_once(&once, init_once); vcos_mutex_lock(&client.lock); count = client.refcount++; if (count > 0) { /* Already initialised so nothing to do */ vcos_mutex_unlock(&client.lock); return MMAL_SUCCESS; } vcos_log_register("mmalipc", VCOS_LOG_CATEGORY); /* Initialise a VCHIQ instance */ vchiq_status = vchiq_initialise(&mmal_vchiq_instance); if (vchiq_status != VCHIQ_SUCCESS) { LOG_ERROR("failed to initialise vchiq"); status = MMAL_EIO; goto error; } vchiq_initialised = 1; vchiq_status = vchiq_connect(mmal_vchiq_instance); if (vchiq_status != VCHIQ_SUCCESS) { LOG_ERROR("failed to connect to vchiq"); status = MMAL_EIO; goto error; } memset(&vchiq_params,0,sizeof(vchiq_params)); vchiq_params.fourcc = MMAL_CONTROL_FOURCC(); vchiq_params.callback = mmal_vc_vchiq_callback; vchiq_params.userdata = &client; vchiq_params.version = WORKER_VER_MAJOR; vchiq_params.version_min = WORKER_VER_MINIMUM; vchiq_status = vchiq_open_service(mmal_vchiq_instance, &vchiq_params, &client.service); if (vchiq_status != VCHIQ_SUCCESS) { LOG_ERROR("could not open vchiq service"); status = MMAL_EIO; goto error; } client.usecount = 1; /* usecount set to 1 by the open call. */ service_initialised = 1; status = create_waitpool(&client.waitpool); if (status != MMAL_SUCCESS) { LOG_ERROR("could not create wait pool"); goto error; } waitpool_initialised = 1; if (vcos_mutex_create(&client.bulk_lock, "mmal client bulk lock") != VCOS_SUCCESS) { LOG_ERROR("could not create bulk lock"); status = MMAL_ENOSPC; goto error; } client.inited = 1; vcos_mutex_unlock(&client.lock); /* assume we're not using VC immediately. Do this outside the lock */ mmal_vc_release(); return MMAL_SUCCESS; error: if (waitpool_initialised) destroy_waitpool(&client.waitpool); if (service_initialised) { client.usecount = 0; vchiq_close_service(client.service); } if (vchiq_initialised) vchiq_shutdown(mmal_vchiq_instance); vcos_log_unregister(VCOS_LOG_CATEGORY); client.refcount--; vcos_mutex_unlock(&client.lock); return status; }