/** Send a buffer header to a port */ MMAL_STATUS_T mmal_port_send_buffer(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_STATUS_T status; if (!port || !port->priv) { LOG_ERROR("invalid port"); return MMAL_EINVAL; } #ifdef ENABLE_MMAL_EXTRA_LOGGING LOG_TRACE("%s(%i:%i) port %p, buffer %p (%p,%i,%i)", port->component->name, (int)port->type, (int)port->index, port, buffer, buffer ? buffer->data: 0, buffer ? (int)buffer->offset : 0, buffer ? (int)buffer->length : 0); #endif if (!buffer->data && !(port->capabilities & MMAL_PORT_CAPABILITY_PASSTHROUGH)) { LOG_ERROR("%s(%p) received invalid buffer header", port->name, port); return MMAL_EINVAL; } if (!port->priv->pf_send) return MMAL_ENOSYS; LOCK_SENDING(port); if (!port->is_enabled) { UNLOCK_SENDING(port); return MMAL_EINVAL; } if (port->type == MMAL_PORT_TYPE_OUTPUT && buffer->length) { LOG_DEBUG("given an output buffer with length != 0"); buffer->length = 0; } IN_TRANSIT_INCREMENT(port); status = port->priv->pf_send(port, buffer); if (status != MMAL_SUCCESS) { IN_TRANSIT_DECREMENT(port); LOG_ERROR("%s: send failed: %s", port->name, mmal_status_to_string(status)); } else { mmal_port_update_port_stats(port, MMAL_CORE_STATS_RX); } UNLOCK_SENDING(port); return status; }
/** Buffer header callback. */ void mmal_port_buffer_header_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { #ifdef ENABLE_MMAL_EXTRA_LOGGING LOG_TRACE("%s(%i:%i) port %p, buffer %p (%i,%p,%i,%i)", port->component->name, (int)port->type, (int)port->index, port, buffer, buffer ? (int)buffer->cmd : 0, buffer ? buffer->data : 0, buffer ? (int)buffer->offset : 0, buffer ? (int)buffer->length : 0); #endif if (!vcos_verify(IN_TRANSIT_COUNT(port) >= 0)) LOG_ERROR("%s: buffer headers in transit < 0 (%d)", port->name, (int)IN_TRANSIT_COUNT(port)); if (MMAL_COLLECT_PORT_STATS_ENABLED) { mmal_port_update_port_stats(port, MMAL_CORE_STATS_TX); } port->priv->core->buffer_header_callback(port, buffer); IN_TRANSIT_DECREMENT(port); }
/** Send a buffer header to a port */ MMAL_STATUS_T mmal_port_send_buffer(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_STATUS_T status = MMAL_SUCCESS; if (!port || !port->priv) { LOG_ERROR("invalid port"); return MMAL_EINVAL; } #ifdef ENABLE_MMAL_EXTRA_LOGGING LOG_TRACE("%s(%i:%i) port %p, buffer %p (%p,%i,%i)", port->component->name, (int)port->type, (int)port->index, port, buffer, buffer ? buffer->data: 0, buffer ? (int)buffer->offset : 0, buffer ? (int)buffer->length : 0); #endif if (!buffer->data && !(port->capabilities & MMAL_PORT_CAPABILITY_PASSTHROUGH)) { LOG_ERROR("%s(%p) received invalid buffer header", port->name, port); return MMAL_EINVAL; } if (!port->priv->pf_send) return MMAL_ENOSYS; LOCK_SENDING(port); if (!port->is_enabled) { UNLOCK_SENDING(port); return MMAL_EINVAL; } if (port->type == MMAL_PORT_TYPE_OUTPUT && buffer->length) { LOG_DEBUG("given an output buffer with length != 0"); buffer->length = 0; } /* coverity[lock] transit_sema is used for signalling, and is not a lock */ /* coverity[lock_order] since transit_sema is not a lock, there is no ordering conflict */ IN_TRANSIT_INCREMENT(port); if (port->priv->core->is_paused) { /* Add buffer to our internal queue */ buffer->next = NULL; *port->priv->core->queue_last = buffer; port->priv->core->queue_last = &buffer->next; } else { /* Send buffer to component */ status = port->priv->pf_send(port, buffer); } if (status != MMAL_SUCCESS) { IN_TRANSIT_DECREMENT(port); LOG_ERROR("%s: send failed: %s", port->name, mmal_status_to_string(status)); } else { mmal_port_update_port_stats(port, MMAL_CORE_STATS_RX); } UNLOCK_SENDING(port); return status; }