static MMAL_STATUS_T mmal_port_connection_start(MMAL_PORT_T *port, MMAL_PORT_T *connected_port) { MMAL_PORT_T *output = port->type == MMAL_PORT_TYPE_OUTPUT ? port : connected_port; MMAL_PORT_T *input = connected_port->type == MMAL_PORT_TYPE_INPUT ? connected_port : port; MMAL_POOL_T *pool = port->priv->core->pool_for_connection ? port->priv->core->pool_for_connection : connected_port->priv->core->pool_for_connection; MMAL_STATUS_T status; if (output->type == MMAL_PORT_TYPE_CLOCK && input->type == MMAL_PORT_TYPE_CLOCK) { /* Clock ports need buffers to send clock updates, so * populate both clock ports */ status = mmal_port_populate_clock_ports(output, input, pool); } else { /* Put the buffers into the output port */ status = mmal_port_populate_from_pool(output, pool); } return status; }
static MMAL_STATUS_T mmal_port_enable_locked_connected(MMAL_PORT_T* output, MMAL_PORT_T* input) { MMAL_PORT_PRIVATE_CORE_T* output_core = output->priv->core; MMAL_STATUS_T status = MMAL_SUCCESS; output_core->buffer_header_callback = mmal_port_connected_output_cb; /* Output port already locked, lock input port */ LOCK_PORT(input); /* Disable connected port if its buffer config needs to change */ if (input->is_enabled && (input->buffer_size != output->buffer_size || input->buffer_num != output->buffer_num)) { status = mmal_port_disable_locked(input); if (status != MMAL_SUCCESS) goto finish; } /* Ensure the connected port has the same buffer configuration */ input->buffer_size = output->buffer_size; input->buffer_num = output->buffer_num; /* Enable other end of the connection, if not already enabled */ if (!input->is_enabled) { status = mmal_port_enable_locked(input, NULL); if (status != MMAL_SUCCESS) goto finish; } if (output_core->allocate_pool) { MMAL_POOL_T* pool = NULL; /* Decide which port will be used to allocate the pool */ MMAL_PORT_T* pool_port = (output->capabilities & MMAL_PORT_CAPABILITY_ALLOCATION) ? output : input; MMAL_PORT_PRIVATE_CORE_T* pool_core = pool_port->priv->core; uint32_t buffer_size = pool_port->buffer_size; /* No need to allocate payload memory for pass-through ports */ if (output->capabilities & MMAL_PORT_CAPABILITY_PASSTHROUGH) buffer_size = 0; UNLOCK_PORT(input); if (pool_port == output) UNLOCK_PORT(output); /* Port pool creation must be done without the lock held */ pool = mmal_port_pool_create(pool_port, pool_port->buffer_num, buffer_size); if (pool_port == output) LOCK_PORT(output); LOCK_PORT(input); if (!pool) { status = MMAL_ENOMEM; goto finish; } pool_core->pool_for_connection = pool; mmal_pool_callback_set(pool_core->pool_for_connection, mmal_port_connected_pool_cb, output); /* Put the buffers into the output port */ status = mmal_port_populate_from_pool(output, pool_port->priv->core->pool_for_connection); } finish: /* At this point, both locks must be held */ if (status != MMAL_SUCCESS && input->is_enabled) mmal_port_disable_locked(input); UNLOCK_PORT(input); if (status != MMAL_SUCCESS) mmal_port_disable_locked(output); return status; }