/** Default behaviour when setting up or tearing down a connection to another port */ static MMAL_STATUS_T mmal_port_connect_default(MMAL_PORT_T *port, MMAL_PORT_T *other_port) { MMAL_PARAM_UNUSED(port); MMAL_PARAM_UNUSED(other_port); LOG_TRACE("port %p, other_port %p", port, other_port); return MMAL_ENOSYS; }
static MMAL_STATUS_T aggregator_parameter_get(MMAL_GRAPH_T *graph, MMAL_PORT_T *port, MMAL_PARAMETER_HEADER_T *param) { MMAL_PARAM_UNUSED(graph); MMAL_PARAM_UNUSED(port); MMAL_PARAM_UNUSED(param); LOG_TRACE("graph %p, port %p, param %p", graph, port, param); return MMAL_ENOSYS; }
/** Enable processing on a port */ static MMAL_STATUS_T splitter_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) { #if 0 MMAL_COMPONENT_T *component = port->component; uint32_t buffer_num, buffer_size; unsigned int i; /* Find the max and apply that to all ports */ buffer_num = component->input[0]->buffer_num; buffer_size = component->input[0]->buffer_size; for (i = 0; i < component->output_num; i++) { buffer_num = MMAL_MAX(buffer_num, component->output[i]->buffer_num); buffer_size = MMAL_MAX(buffer_num, component->output[i]->buffer_size); } component->input[0]->buffer_num = buffer_num; component->input[0]->buffer_size = buffer_size; for (i = 0; i < component->output_num; i++) { component->output[i]->buffer_num = buffer_num; component->output[i]->buffer_size = buffer_num; } #endif MMAL_PARAM_UNUSED(cb); if (port->buffer_size) if (port->type == MMAL_PORT_TYPE_OUTPUT) port->component->priv->module->enabled_flags |= (1<<port->index); return MMAL_SUCCESS; }
/** Callback from an input port. Buffer is released. */ static void mmal_connection_bh_in_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_PARAM_UNUSED(port); LOG_TRACE("(%s)%p,%p,%p,%i", port->name, port, buffer, buffer->data, (int)buffer->length); /* We're done with the buffer, just recycle it */ mmal_buffer_header_release(buffer); }
/** Create an instance of a component */ static MMAL_STATUS_T mmal_component_create_splitter(const char *name, MMAL_COMPONENT_T *component) { MMAL_COMPONENT_MODULE_T *module; MMAL_STATUS_T status = MMAL_ENOMEM; unsigned int i; MMAL_PARAM_UNUSED(name); /* Allocate the context for our module */ component->priv->module = module = vcos_malloc(sizeof(*module), "mmal module"); if (!module) return MMAL_ENOMEM; memset(module, 0, sizeof(*module)); component->priv->pf_destroy = splitter_component_destroy; /* Allocate and initialise all the ports for this component */ component->input = mmal_ports_alloc(component, 1, MMAL_PORT_TYPE_INPUT, sizeof(MMAL_PORT_MODULE_T)); if(!component->input) goto error; component->input_num = 1; component->input[0]->priv->pf_enable = splitter_port_enable; component->input[0]->priv->pf_disable = splitter_port_disable; component->input[0]->priv->pf_flush = splitter_port_flush; component->input[0]->priv->pf_send = splitter_port_send; component->input[0]->priv->pf_set_format = splitter_port_format_commit; component->input[0]->priv->pf_parameter_set = splitter_port_parameter_set; component->input[0]->buffer_num_min = 1; component->input[0]->buffer_num_recommended = 0; component->input[0]->priv->module->queue = mmal_queue_create(); if(!component->input[0]->priv->module->queue) goto error; component->output = mmal_ports_alloc(component, SPLITTER_OUTPUT_PORTS_NUM, MMAL_PORT_TYPE_OUTPUT, sizeof(MMAL_PORT_MODULE_T)); if(!component->output) goto error; component->output_num = SPLITTER_OUTPUT_PORTS_NUM; for(i = 0; i < component->output_num; i++) { component->output[i]->priv->pf_enable = splitter_port_enable; component->output[i]->priv->pf_disable = splitter_port_disable; component->output[i]->priv->pf_flush = splitter_port_flush; component->output[i]->priv->pf_send = splitter_port_send; component->output[i]->priv->pf_set_format = splitter_port_format_commit; component->output[i]->priv->pf_parameter_set = splitter_port_parameter_set; component->output[i]->buffer_num_min = 1; component->output[i]->buffer_num_recommended = 0; component->output[i]->capabilities = MMAL_PORT_CAPABILITY_PASSTHROUGH; component->output[i]->priv->module->queue = mmal_queue_create(); if(!component->output[i]->priv->module->queue) goto error; } return MMAL_SUCCESS; error: splitter_component_destroy(component); return status; }
/** Connected input port buffer callback */ static void mmal_port_connected_input_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_PARAM_UNUSED(port); LOG_TRACE("buffer %p from connected input port %p: data %p, alloc_size %u, length %u", buffer, port, buffer->data, buffer->alloc_size, buffer->length); /* Simply release buffer back into pool for re-use */ mmal_buffer_header_release(buffer); }
/** Lock a shared memory buffer */ uint8_t *mmal_vc_shm_lock(uint8_t *mem, uint32_t workaround) { /* Zero copy stuff */ MMAL_VC_PAYLOAD_ELEM_T *elem = mmal_vc_payload_list_find_handle(mem); MMAL_PARAM_UNUSED(workaround); if (elem) mem = elem->mem; return mem; }
/** Callback from an output port. Buffer is queued for the next component. */ static void mmal_connection_bh_out_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_CONNECTION_T *connection = (MMAL_CONNECTION_T *)port->userdata; MMAL_PARAM_UNUSED(port); LOG_TRACE("(%s)%p,%p,%p,%i", port->name, port, buffer, buffer->data, (int)buffer->length); /* Queue the buffer produced by the output port */ mmal_queue_put(connection->queue, buffer); if (connection->callback) connection->callback(connection); }
/** Callback from the pool. Buffer is available. */ static MMAL_BOOL_T mmal_connection_bh_release_cb(MMAL_POOL_T *pool, MMAL_BUFFER_HEADER_T *buffer, void *userdata) { MMAL_CONNECTION_T *connection = (MMAL_CONNECTION_T *)userdata; MMAL_PARAM_UNUSED(pool); mmal_queue_put(pool->queue, buffer); if (connection->callback) connection->callback(connection); return 0; }
/** Callback for when a buffer from a connected input port is finally released */ static MMAL_BOOL_T mmal_port_connected_pool_cb(MMAL_POOL_T *pool, MMAL_BUFFER_HEADER_T *buffer, void *userdata) { MMAL_PORT_T* port = (MMAL_PORT_T*)userdata; MMAL_STATUS_T status; MMAL_PARAM_UNUSED(pool); LOG_TRACE("released buffer %p, data %p alloc_size %u length %u", buffer, buffer->data, buffer->alloc_size, buffer->length); /* Pipe the buffer back to the output port */ status = mmal_port_send_buffer(port, buffer); /* Put the buffer back in the pool if we were successful */ return status != MMAL_SUCCESS; }
/** Unlock a shared memory buffer */ uint8_t *mmal_vc_shm_unlock(uint8_t *mem, uint32_t *length, uint32_t workaround) { /* Zero copy stuff */ MMAL_VC_PAYLOAD_ELEM_T *elem = mmal_vc_payload_list_find_mem(mem); MMAL_PARAM_UNUSED(workaround); if (elem) { *length = 0; mem = (uint8_t *)elem->vc_handle; #ifdef ENABLE_MMAL_VCSM vcsm_unlock_ptr(elem->mem); #endif /* ENABLE_MMAL_VCSM */ } return mem; }
static MMAL_STATUS_T mmalplay_setup_container_writer(MMALPLAY_T *ctx, MMAL_COMPONENT_T *writer, const char *uri) { MMAL_PARAMETER_URI_T *param = 0; unsigned int param_size; MMAL_STATUS_T status = MMAL_EINVAL; size_t uri_len; MMAL_PARAM_UNUSED(ctx); if(!writer->input_num) { LOG_ERROR("%s doesn't have input ports", writer->name); goto error; } /* Open the given URI */ uri_len = strlen(uri); param_size = sizeof(MMAL_PARAMETER_HEADER_T) + uri_len; param = malloc(param_size); if(!param) { LOG_ERROR("out of memory"); status = MMAL_ENOMEM; goto error; } memset(param, 0, param_size); param->hdr.id = MMAL_PARAMETER_URI; param->hdr.size = param_size; vcos_safe_strcpy(param->uri, uri, uri_len + 1, 0); status = mmal_port_parameter_set(writer->control, ¶m->hdr); if(status != MMAL_SUCCESS) { LOG_ERROR("could not open file %s", uri); goto error; } error: if(param) free(param); return status; }
void test_signal_handler(int signum) { static MMAL_BOOL_T stopped_already = 0; int i; MMAL_PARAM_UNUSED(signum); if (stopped_already) { LOG_ERROR("Killing program"); exit(255); } stopped_already = 1; LOG_ERROR("BYE"); 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); } }
/** Allocate a shared memory buffer */ uint8_t *mmal_vc_shm_alloc(uint32_t size) { uint8_t *mem = NULL; MMAL_VC_PAYLOAD_ELEM_T *payload_elem = mmal_vc_payload_list_get(); if (!payload_elem) { LOG_ERROR("could not get a free slot in the payload list"); return NULL; } #ifdef ENABLE_MMAL_VCSM unsigned int vcsm_handle = vcsm_malloc_cache(size, VCSM_CACHE_TYPE_NONE, "mmal_vc_port buffer"); unsigned int vc_handle = vcsm_vc_hdl_from_hdl(vcsm_handle); mem = (uint8_t *)vcsm_lock( vcsm_handle ); if (!mem || !vc_handle) { LOG_ERROR("could not allocate %i bytes of shared memory (handle %x)", (int)size, vcsm_handle); if (mem) vcsm_unlock_hdl(vcsm_handle); if (vcsm_handle) vcsm_free(vcsm_handle); mmal_vc_payload_list_release(payload_elem); return NULL; } payload_elem->mem = mem; payload_elem->handle = (void *)vcsm_handle; payload_elem->vc_handle = (void *)vc_handle; #else /* ENABLE_MMAL_VCSM */ MMAL_PARAM_UNUSED(size); mmal_vc_payload_list_release(payload_elem); #endif /* ENABLE_MMAL_VCSM */ return mem; }
/** Enable processing on a port */ static MMAL_STATUS_T mmal_vc_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) { MMAL_PORT_MODULE_T *module = port->priv->module; MMAL_STATUS_T status; mmal_worker_reply reply; mmal_worker_port_action msg; size_t replylen = sizeof(reply); MMAL_PARAM_UNUSED(cb); if (!port->component->priv->module->event_ctx_initialised) { MMAL_POOL_T *pool = port->component->priv->event_pool; MMAL_DRIVER_BUFFER_T *drv; unsigned int i; /* We need to associate our vc client context to all our event buffers. * This only needs to be done when the first port is enabled because no event * can be received on disabled ports. */ for (i = 0; i < pool->headers_num; i++) { drv = mmal_buffer_header_driver_data(pool->header[i]); drv->client_context = &port->component->priv->module->event_ctx; drv->magic = MMAL_MAGIC; } port->component->priv->module->event_ctx_initialised = MMAL_TRUE; } if (!module->connected) { if (vcos_blockpool_create_on_heap(&module->pool, port->buffer_num, sizeof(MMAL_VC_CLIENT_BUFFER_CONTEXT_T), VCOS_BLOCKPOOL_ALIGN_DEFAULT, VCOS_BLOCKPOOL_FLAG_NONE, "mmal vc port pool") != VCOS_SUCCESS) { LOG_ERROR("failed to create port pool"); return MMAL_ENOMEM; } module->has_pool = 1; } if (module->connected) { /* The connected port won't be enabled explicitly so make sure we apply * the buffer requirements now. */ status = mmal_vc_port_requirements_set(module->connected); if (status != MMAL_SUCCESS) goto error; } msg.component_handle = module->component_handle; msg.action = MMAL_WORKER_PORT_ACTION_ENABLE; msg.port_handle = module->port_handle; msg.param.enable.port = *port; status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), MMAL_WORKER_PORT_ACTION, &reply, &replylen, MMAL_FALSE); if (status == MMAL_SUCCESS) { vcos_assert(replylen == sizeof(reply)); status = reply.status; } if (status != MMAL_SUCCESS) { LOG_ERROR("failed to enable port %s: %s", port->name, mmal_status_to_string(status)); goto error; } if (module->connected) mmal_vc_port_info_get(module->connected); return MMAL_SUCCESS; error: if (module->has_pool) vcos_blockpool_delete(&module->pool); return status; }
static void mmal_port_clock_payload_free(MMAL_PORT_T *port, uint8_t *payload) { MMAL_PARAM_UNUSED(port); mem_release((MEM_HANDLE_T)payload); }
static MMAL_STATUS_T mmal_port_clock_connect(MMAL_PORT_T *port, MMAL_PORT_T *other_port) { MMAL_PARAM_UNUSED(port); MMAL_PARAM_UNUSED(other_port); return MMAL_ENOSYS; }
static MMAL_STATUS_T mmal_port_clock_set_format(MMAL_PORT_T *port) { MMAL_PARAM_UNUSED(port); return MMAL_SUCCESS; }
static MMAL_STATUS_T mmal_port_clock_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb) { MMAL_PARAM_UNUSED(port); MMAL_PARAM_UNUSED(cb); return MMAL_SUCCESS; }
static void *mmal_pool_allocator_default_alloc(void *context, uint32_t size) { MMAL_PARAM_UNUSED(context); return vcos_malloc(size, "mmal_pool payload"); }
static void mmal_pool_allocator_default_free(void *context, void *mem) { MMAL_PARAM_UNUSED(context); vcos_free(mem); }
/** Disable processing on a port */ static MMAL_STATUS_T sdl_port_disable(MMAL_PORT_T *port) { MMAL_PARAM_UNUSED(port); return MMAL_SUCCESS; }