Beispiel #1
0
/** 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;
}
Beispiel #2
0
/** 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;
}
Beispiel #3
0
/** 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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
/** 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;
}
Beispiel #11
0
/** 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;
}
Beispiel #12
0
/** 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;
}