/** Get port buffer requirements. */ static MMAL_STATUS_T mmal_vc_port_requirements_get(MMAL_PORT_T *port) { MMAL_PORT_MODULE_T *module = port->priv->module; mmal_worker_port_info_get msg; mmal_worker_port_info reply; size_t replylen = sizeof(reply); MMAL_STATUS_T status; msg.component_handle = module->component_handle; msg.port_type = port->type; msg.index = port->index; LOG_TRACE("get port requirements (%i:%i)", port->type, port->index); status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), MMAL_WORKER_PORT_INFO_GET, &reply, &replylen, MMAL_FALSE); if (status == MMAL_SUCCESS) { vcos_assert(replylen == sizeof(reply)); status = reply.status; } if (status != MMAL_SUCCESS) { LOG_ERROR("failed to get port requirements (%i:%i)", port->type, port->index); return status; } port->buffer_num_min = reply.port.buffer_num_min; port->buffer_num_recommended = reply.port.buffer_num_recommended; port->buffer_size_min = reply.port.buffer_size_min; port->buffer_size_recommended = reply.port.buffer_size_recommended; port->buffer_alignment_min = reply.port.buffer_alignment_min; return MMAL_SUCCESS; }
/** Flush a port using PORT_FLUSH - generates a dummy bulk transfer to keep it in sync * with buffers being passed using bulk transfer */ static MMAL_STATUS_T mmal_vc_port_flush_sync(MMAL_PORT_T *port) { MMAL_PORT_MODULE_T *module = port->priv->module; MMAL_STATUS_T status; mmal_worker_reply reply; MMAL_VC_CLIENT_BUFFER_CONTEXT_T client_context; mmal_worker_buffer_from_host *msg; size_t replylen = sizeof(reply); msg = &client_context.msg; client_context.magic = MMAL_MAGIC; client_context.port = port; msg->drvbuf.client_context = &client_context; msg->drvbuf.component_handle = module->component_handle; msg->drvbuf.port_handle = module->port_handle; msg->drvbuf.magic = MMAL_MAGIC; status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg->header, sizeof(*msg), MMAL_WORKER_PORT_FLUSH, &reply, &replylen, MMAL_TRUE); if (status == MMAL_SUCCESS) { vcos_assert(replylen == sizeof(reply)); status = reply.status; } if (status != MMAL_SUCCESS) LOG_ERROR("failed to disable port - reason %d", status); return status; }
/** Set port buffer requirements. */ static MMAL_STATUS_T mmal_vc_port_requirements_set(MMAL_PORT_T *port) { 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); msg.component_handle = module->component_handle; msg.action = MMAL_WORKER_PORT_ACTION_SET_REQUIREMENTS; 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 set port requirements (%i/%i,%i/%i)", port->buffer_num, port->buffer_num_min, port->buffer_size, port->buffer_size_min); return status; }
MMAL_STATUS_T mmal_vc_opaque_release(unsigned int handle) { MMAL_STATUS_T ret; mmal_worker_opaque_allocator msg; size_t len = sizeof(msg); msg.handle = handle; msg.op = MMAL_WORKER_OPAQUE_MEM_RELEASE; ret = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), MMAL_WORKER_OPAQUE_ALLOCATOR, &msg, &len, MMAL_FALSE); if (ret == MMAL_SUCCESS) ret = msg.status; return ret; }
int mmal_vc_drm_get_time(unsigned int * time) { MMAL_STATUS_T status; mmal_worker_msg_header req; mmal_worker_drm_get_time_reply reply; size_t len = sizeof(reply); status = mmal_vc_init(); if (status != MMAL_SUCCESS) return status; status = mmal_vc_sendwait_message(mmal_vc_get_client(), &req, sizeof(req), MMAL_WORKER_DRM_GET_TIME, &reply, &len, MMAL_FALSE); *time = reply.time; mmal_vc_deinit(); return status; }
int mmal_vc_drm_get_lhs32(unsigned char * into) { MMAL_STATUS_T status; mmal_worker_msg_header req; mmal_worker_drm_get_lhs32_reply reply; size_t len = sizeof(reply); status = mmal_vc_init(); if (status != MMAL_SUCCESS) return status; status = mmal_vc_sendwait_message(mmal_vc_get_client(), &req, sizeof(req), MMAL_WORKER_DRM_GET_LHS32, &reply, &len, MMAL_FALSE); memcpy(into, reply.secret, 32); mmal_vc_deinit(); return status; }
MMAL_OPAQUE_IMAGE_HANDLE_T mmal_vc_opaque_alloc_desc(const char *description) { MMAL_STATUS_T ret; MMAL_OPAQUE_IMAGE_HANDLE_T h = 0; mmal_worker_opaque_allocator msg; size_t len = sizeof(msg); msg.op = MMAL_WORKER_OPAQUE_MEM_ALLOC; vcos_safe_strcpy(msg.description, description, sizeof(msg.description), 0); ret = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), MMAL_WORKER_OPAQUE_ALLOCATOR_DESC, &msg, &len, MMAL_FALSE); if (ret == MMAL_SUCCESS) { h = msg.handle; } return h; }
MMAL_STATUS_T mmal_vc_get_stats(MMAL_VC_STATS_T *stats, int reset) { mmal_worker_stats msg; size_t len = sizeof(msg); msg.reset = reset; MMAL_STATUS_T status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), MMAL_WORKER_GET_STATS, &msg, &len, MMAL_FALSE); if (status == MMAL_SUCCESS) { vcos_assert(len == sizeof(msg)); *stats = msg.stats; } return status; }
MMAL_STATUS_T mmal_vc_get_version(uint32_t *major, uint32_t *minor, uint32_t *minimum) { mmal_worker_version msg; size_t len = sizeof(msg); MMAL_STATUS_T status; status = mmal_vc_sendwait_message(mmal_vc_get_client(), &msg.header, sizeof(msg), MMAL_WORKER_GET_VERSION, &msg, &len, MMAL_FALSE); if (status != MMAL_SUCCESS) return status; if (!vcos_verify(len == sizeof(msg))) return MMAL_EINVAL; *major = msg.major; *minor = msg.minor; *minimum = msg.minimum; return MMAL_SUCCESS; }
/** Disable processing on a port */ static MMAL_STATUS_T mmal_vc_port_disable(MMAL_PORT_T *port) { 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); msg.component_handle = module->component_handle; msg.action = MMAL_WORKER_PORT_ACTION_DISABLE; msg.port_handle = module->port_handle; 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 disable port - reason %d", status); if (module->has_pool) { /* MMAL server should make sure that all buffers are sent back before it * disables the port. */ vcos_assert(vcos_blockpool_available_count(&module->pool) == port->buffer_num); vcos_blockpool_delete(&module->pool); module->has_pool = 0; } /* We need to make sure all the queued callbacks have been done */ while (mmal_queue_length(port->component->priv->module->callback_queue)) mmal_vc_do_callback(port->component); if (module->connected) mmal_vc_port_info_get(module->connected); return status; }
/** Flush a port using MMAL_WORKER_PORT_ACTION - when the port is zero-copy or no data has been sent */ static MMAL_STATUS_T mmal_vc_port_flush_normal(MMAL_PORT_T *port) { 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); msg.component_handle = module->component_handle; msg.action = MMAL_WORKER_PORT_ACTION_FLUSH; msg.port_handle = module->port_handle; 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 disable port - reason %d", status); return status; }
/** 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; }