Ejemplo n.º 1
0
MMAL_BOOL_T mmal_port_is_connected(MMAL_PORT_T *port)
{
   MMAL_PORT_PRIVATE_CORE_T *core;
   MMAL_PORT_T *connected_port;

   if (!port || !port->priv || !port->priv->core)
      return MMAL_FALSE;

   core = port->priv->core;
   LOCK_CONNECTION(port);
   connected_port = core->connected_port;
   UNLOCK_CONNECTION(port);
   return !!connected_port;
}
Ejemplo n.º 2
0
/** Connect an output port to an input port. */
MMAL_STATUS_T mmal_port_connect(MMAL_PORT_T *port, MMAL_PORT_T *other_port)
{
   MMAL_PORT_PRIVATE_CORE_T* core;
   MMAL_PORT_PRIVATE_CORE_T* other_core;
   MMAL_STATUS_T status = MMAL_SUCCESS;
   MMAL_PORT_T* output_port = NULL;

   if (!port || !port->priv || !other_port || !other_port->priv)
   {
      LOG_ERROR("invalid port");
      return MMAL_EINVAL;
   }

   if ((port->type == MMAL_PORT_TYPE_CLOCK) && (port->type != other_port->type))
   {
      LOG_ERROR("invalid port connection");
      return MMAL_EINVAL;
   }

   LOG_TRACE("connecting %s(%p) to %s(%p)", port->name, port, other_port->name, other_port);

   if (!port->priv->pf_connect || !other_port->priv->pf_connect)
   {
      LOG_ERROR("at least one pf_connect is NULL");
      return MMAL_ENOSYS;
   }

   core = port->priv->core;
   other_core = other_port->priv->core;

   LOCK_CONNECTION(port);
   if (core->connected_port)
   {
      LOG_ERROR("port %p is already connected", port);
      UNLOCK_CONNECTION(port);
      return MMAL_EISCONN;
   }
   if (port->is_enabled)
   {
      LOG_ERROR("port %p should not be enabled", port);
      UNLOCK_CONNECTION(port);
      return MMAL_EINVAL;
   }

   LOCK_CONNECTION(other_port);
   if (other_core->connected_port)
   {
      LOG_ERROR("port %p is already connected", other_port);
      status = MMAL_EISCONN;
      goto finish;
   }
   if (other_port->is_enabled)
   {
      LOG_ERROR("port %p should not be enabled", other_port);
      status = MMAL_EINVAL;
      goto finish;
   }

   core->connected_port = other_port;
   other_core->connected_port = port;

   core->core_owns_connection = 0;
   other_core->core_owns_connection = 0;

   /* Check to see if the port will manage the connection on its own. If not then the core
    * will manage it. */
   output_port = port->type == MMAL_PORT_TYPE_OUTPUT ? port : other_port;
   if (output_port->priv->pf_connect(port, other_port) == MMAL_SUCCESS)
      goto finish;

   core->core_owns_connection = 1;
   other_core->core_owns_connection = 1;


finish:
   UNLOCK_CONNECTION(other_port);
   UNLOCK_CONNECTION(port);
   return status;
}
Ejemplo n.º 3
0
/** Disable processing on a port */
MMAL_STATUS_T mmal_port_disable(MMAL_PORT_T *port)
{
   MMAL_STATUS_T status;
   MMAL_PORT_T *connected_port;
   MMAL_PORT_PRIVATE_CORE_T *core;

   if (!port || !port->priv)
      return MMAL_EINVAL;

   LOG_TRACE("%s(%i:%i) port %p", port->component->name,
             (int)port->type, (int)port->index, port);

   if (!port->priv->pf_disable)
      return MMAL_ENOSYS;

   core = port->priv->core;
   LOCK_CONNECTION(port);
   connected_port = core->connected_port;

   /* Sanity checking */
   if (!port->is_enabled)
   {
      UNLOCK_CONNECTION(port);
      LOG_ERROR("port %s(%p) is not enabled", port->name, port);
      return MMAL_EINVAL;
   }

   if (connected_port)
      LOCK_CONNECTION(connected_port);

   /* Disable the output port of a connection first */
   if (connected_port && connected_port->type != MMAL_PORT_TYPE_INPUT)
   {
      status = mmal_port_disable_internal(connected_port);
      if (status != MMAL_SUCCESS)
      {
         LOG_ERROR("failed to disable connected port (%s)%p (%s)", connected_port->name,
            connected_port, mmal_status_to_string(status));
         goto end;
      }
   }

   status = mmal_port_disable_internal(port);
   if (status != MMAL_SUCCESS)
   {
      LOG_ERROR("failed to disable port (%s)%p", port->name, port);
      goto end;
   }

   /* Disable the input port of a connection last */
   if (connected_port && connected_port->type == MMAL_PORT_TYPE_INPUT)
   {
      status = mmal_port_disable_internal(connected_port);
      if (status != MMAL_SUCCESS)
      {
         LOG_ERROR("failed to disable connected port (%s)%p (%s)", connected_port->name,
            connected_port, mmal_status_to_string(status));
         goto end;
      }
   }

   if (connected_port)
   {
      status = mmal_port_connection_disable(port, connected_port);
      if (status != MMAL_SUCCESS)
         LOG_ERROR("failed to disable connection (%s)%p (%s)", port->name,
            port, mmal_status_to_string(status));
   }

end:
   if (connected_port)
      UNLOCK_CONNECTION(connected_port);
   UNLOCK_CONNECTION(port);

   return status;
}
Ejemplo n.º 4
0
/** Enable processing on a port */
MMAL_STATUS_T mmal_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb)
{
   MMAL_STATUS_T status;
   MMAL_PORT_T *connected_port;
   MMAL_PORT_PRIVATE_CORE_T *core;

   if (!port || !port->priv)
      return MMAL_EINVAL;

   LOG_TRACE("%s port %p, cb %p, buffers (%i/%i/%i,%i/%i/%i)",
             port->name, port, cb,
             (int)port->buffer_num, (int)port->buffer_num_recommended, (int)port->buffer_num_min,
             (int)port->buffer_size, (int)port->buffer_size_recommended, (int)port->buffer_size_min);

   if (!port->priv->pf_enable)
      return MMAL_ENOSYS;

   core = port->priv->core;
   LOCK_CONNECTION(port);
   connected_port = core->connected_port;

   /* Sanity checking */
   if (port->is_enabled)
   {
      UNLOCK_CONNECTION(port);
      LOG_ERROR("%s(%p) already enabled", port->name, port);
      return MMAL_EINVAL;
   }
   if (connected_port && cb) /* Callback must be NULL for connected ports */
   {
      UNLOCK_CONNECTION(port);
      LOG_ERROR("callback (%p) not allowed for connected port (%s)%p",
         cb, port->name, connected_port);
      return MMAL_EINVAL;
   }

   /* Start by preparing the port connection so that everything is ready for when
    * both ports are enabled */
   if (connected_port)
   {
      LOCK_CONNECTION(connected_port);
      status = mmal_port_connection_enable(port, connected_port);
      if (status != MMAL_SUCCESS)
      {
         UNLOCK_CONNECTION(connected_port);
         UNLOCK_CONNECTION(port);
         return status;
      }

      cb = connected_port->type == MMAL_PORT_TYPE_INPUT ?
         mmal_port_connected_output_cb : mmal_port_connected_input_cb;
   }

   /* Enable the input port of a connection first */
   if (connected_port && connected_port->type == MMAL_PORT_TYPE_INPUT)
   {
      status = mmal_port_enable_internal(connected_port, mmal_port_connected_input_cb);
      if (status != MMAL_SUCCESS)
      {
         LOG_ERROR("failed to enable connected port (%s)%p (%s)", connected_port->name,
            connected_port, mmal_status_to_string(status));
         goto error;
      }
   }

   status = mmal_port_enable_internal(port, cb);
   if (status != MMAL_SUCCESS)
   {
      LOG_ERROR("failed to enable port %s(%p) (%s)", port->name, port,
         mmal_status_to_string(status));
      goto error;
   }

   /* Enable the output port of a connection last */
   if (connected_port && connected_port->type != MMAL_PORT_TYPE_INPUT)
   {
      status = mmal_port_enable_internal(connected_port, mmal_port_connected_output_cb);
      if (status != MMAL_SUCCESS)
      {
         LOG_ERROR("failed to enable connected port (%s)%p (%s)", connected_port->name,
            connected_port, mmal_status_to_string(status));
         goto error;
      }
   }

   /* Kick off the connection */
   if (connected_port && core->core_owns_connection)
   {
      status = mmal_port_connection_start(port, connected_port);
      if (status != MMAL_SUCCESS)
      {
         LOG_ERROR("failed to start connection (%s)%p (%s)", port->name,
            port, mmal_status_to_string(status));
         goto error;
      }
   }

   if (connected_port)
      UNLOCK_CONNECTION(connected_port);
   UNLOCK_CONNECTION(port);
   return MMAL_SUCCESS;

error:
   if (connected_port && connected_port->is_enabled)
      mmal_port_disable_internal(connected_port);
   if (port->is_enabled)
      mmal_port_disable_internal(port);
   if (connected_port)
      mmal_port_connection_disable(port, connected_port);

   if (connected_port)
      UNLOCK_CONNECTION(connected_port);
   UNLOCK_CONNECTION(port);
   return status;
}
Ejemplo n.º 5
0
/** Disconnect a connected port. */
MMAL_STATUS_T mmal_port_disconnect(MMAL_PORT_T *port)
{
   MMAL_PORT_PRIVATE_CORE_T* core;
   MMAL_PORT_T* other_port;
   MMAL_STATUS_T status = MMAL_SUCCESS;

   if (!port || !port->priv)
   {
      LOG_ERROR("invalid port");
      return MMAL_EINVAL;
   }

   LOG_TRACE("%s(%p)", port->name, port);

   LOCK_CONNECTION(port);

   core = port->priv->core;
   other_port = core->connected_port;

   if (!other_port)
   {
      UNLOCK_CONNECTION(port);
      LOG_DEBUG("%s(%p) is not connected", port->name, port);
      return MMAL_ENOTCONN;
   }

   LOCK_CONNECTION(other_port);

   /* Make sure the connection is disabled first */
   if (port->is_enabled)
   {
      MMAL_PORT_T *output = port->type == MMAL_PORT_TYPE_OUTPUT ? port : other_port;
      MMAL_PORT_T *input = other_port->type == MMAL_PORT_TYPE_INPUT ? other_port : port;

      status = mmal_port_disable_internal(output);
      if (status != MMAL_SUCCESS)
      {
         LOG_ERROR("failed to disable port (%s)%p", port->name, port);
         goto end;
      }
      status = mmal_port_disable_internal(input);
      if (status != MMAL_SUCCESS)
      {
         LOG_ERROR("failed to disable port (%s)%p", port->name, port);
         goto end;
      }
      status = mmal_port_connection_disable(port, other_port);
   }

   if (!core->core_owns_connection)
   {
      status = port->priv->pf_connect(port, NULL);
      if (status != MMAL_SUCCESS)
      {
         LOG_ERROR("disconnection of %s(%p) failed (%i)", port->name, port, status);
         goto end;
      }
   }

   core->connected_port = NULL;
   other_port->priv->core->connected_port = NULL;

end:
   UNLOCK_CONNECTION(other_port);
   UNLOCK_CONNECTION(port);
   return status;
}