mirror of
https://github.com/raspberrypi/userland.git
synced 2025-12-06 04:49:12 +00:00
Revert "mmal: Support 64 bit clients"
This reverts commit c2cd8020ed571c2db13d2ba99695c654136fb440.
This commit is contained in:
@@ -85,10 +85,8 @@ typedef struct MMAL_COMPONENT_MODULE_T
|
||||
|
||||
MMAL_BOOL_T event_ctx_initialised;
|
||||
MMAL_VC_CLIENT_BUFFER_CONTEXT_T event_ctx; /**< Used as the ctx for event buffers */
|
||||
uint32_t event_ctx_handle; /**< Used as the ctx for event buffers */
|
||||
} MMAL_COMPONENT_MODULE_T;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Local function prototypes
|
||||
*****************************************************************************/
|
||||
@@ -150,8 +148,7 @@ static MMAL_STATUS_T mmal_vc_port_requirements_set(MMAL_PORT_T *port)
|
||||
msg.component_handle = module->component_handle;
|
||||
msg.action = MMAL_WORKER_PORT_ACTION_SET_REQUIREMENTS;
|
||||
msg.port_handle = module->port_handle;
|
||||
msg.param.enable.port.buffer_num = port->buffer_num;
|
||||
msg.param.enable.port.buffer_size = port->buffer_size;
|
||||
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);
|
||||
@@ -227,7 +224,7 @@ static MMAL_STATUS_T mmal_vc_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb
|
||||
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_handle;
|
||||
drv->client_context = &port->component->priv->module->event_ctx;
|
||||
drv->magic = MMAL_MAGIC;
|
||||
}
|
||||
|
||||
@@ -258,8 +255,7 @@ static MMAL_STATUS_T mmal_vc_port_enable(MMAL_PORT_T *port, MMAL_PORT_BH_CB_T cb
|
||||
msg.component_handle = module->component_handle;
|
||||
msg.action = MMAL_WORKER_PORT_ACTION_ENABLE;
|
||||
msg.port_handle = module->port_handle;
|
||||
msg.param.enable.port.buffer_num = port->buffer_num;
|
||||
msg.param.enable.port.buffer_size = port->buffer_size;
|
||||
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);
|
||||
@@ -372,7 +368,7 @@ static MMAL_STATUS_T mmal_vc_port_flush_sync(MMAL_PORT_T *port)
|
||||
client_context.magic = MMAL_MAGIC;
|
||||
client_context.port = port;
|
||||
|
||||
msg->drvbuf.client_context = mmal_vc_allocate_client_context(&client_context);
|
||||
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;
|
||||
@@ -388,7 +384,6 @@ static MMAL_STATUS_T mmal_vc_port_flush_sync(MMAL_PORT_T *port)
|
||||
if (status != MMAL_SUCCESS)
|
||||
LOG_ERROR("failed to disable port - reason %d", status);
|
||||
|
||||
mmal_vc_release_client_context(&client_context);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -507,7 +502,7 @@ static void mmal_vc_do_callback(MMAL_COMPONENT_T *component)
|
||||
|
||||
/* Events generated by this component are handled differently */
|
||||
if (mmal_buffer_header_driver_data(buffer)->client_context ==
|
||||
component->priv->module->event_ctx_handle)
|
||||
&component->priv->module->event_ctx)
|
||||
{
|
||||
mmal_port_event_send(port, buffer);
|
||||
return;
|
||||
@@ -533,16 +528,14 @@ static void mmal_vc_port_send_callback(mmal_worker_buffer_from_host *msg)
|
||||
{
|
||||
MMAL_BUFFER_HEADER_T *buffer;
|
||||
MMAL_PORT_T *port;
|
||||
MMAL_VC_CLIENT_BUFFER_CONTEXT_T *client_context = mmal_vc_lookup_client_context(msg->drvbuf.client_context);
|
||||
MMAL_VC_CLIENT_BUFFER_CONTEXT_T *client_context = msg->drvbuf.client_context;
|
||||
|
||||
vcos_assert(client_context);
|
||||
vcos_assert(client_context->magic == MMAL_MAGIC);
|
||||
|
||||
buffer = client_context->buffer;
|
||||
port = client_context->port;
|
||||
|
||||
vcos_blockpool_free(client_context);
|
||||
mmal_vc_release_client_context(client_context);
|
||||
vcos_blockpool_free(msg->drvbuf.client_context);
|
||||
|
||||
vcos_assert(port->priv->module->magic == MMAL_MAGIC);
|
||||
mmal_vc_msg_to_buffer_header(buffer, msg);
|
||||
@@ -621,7 +614,7 @@ static MMAL_STATUS_T mmal_vc_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *
|
||||
client_context->callback_event = NULL;
|
||||
client_context->port = port;
|
||||
|
||||
msg->drvbuf.client_context = mmal_vc_allocate_client_context(client_context);
|
||||
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;
|
||||
@@ -648,14 +641,12 @@ static MMAL_STATUS_T mmal_vc_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *
|
||||
if (!VCOS_BLOCKPOOL_IS_VALID_HANDLE_FORMAT(msg->drvbuf.component_handle, 256))
|
||||
{
|
||||
LOG_ERROR("bad component handle 0x%x", msg->drvbuf.component_handle);
|
||||
mmal_vc_release_client_context(client_context);
|
||||
return MMAL_EINVAL;
|
||||
}
|
||||
|
||||
if (msg->drvbuf.port_handle > 255)
|
||||
{
|
||||
LOG_ERROR("bad port handle 0x%x", msg->drvbuf.port_handle);
|
||||
mmal_vc_release_client_context(client_context);
|
||||
return MMAL_EINVAL;
|
||||
}
|
||||
|
||||
@@ -702,8 +693,7 @@ static MMAL_STATUS_T mmal_vc_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *
|
||||
if (status != MMAL_SUCCESS)
|
||||
{
|
||||
LOG_INFO("failed %d", status);
|
||||
vcos_blockpool_free(client_context);
|
||||
mmal_vc_release_client_context(client_context);
|
||||
vcos_blockpool_free(msg->drvbuf.client_context);
|
||||
buffer->data = mmal_vc_shm_lock(buffer->data, port->priv->module->zero_copy_workaround);
|
||||
}
|
||||
|
||||
@@ -805,7 +795,6 @@ static MMAL_STATUS_T mmal_vc_component_destroy(MMAL_COMPONENT_T *component)
|
||||
mmal_ports_free(component->clock, component->clock_num);
|
||||
|
||||
mmal_queue_destroy(component->priv->module->callback_queue);
|
||||
mmal_vc_release_client_context(&component->priv->module->event_ctx);
|
||||
|
||||
vcos_free(component->priv->module);
|
||||
component->priv->module = NULL;
|
||||
@@ -813,7 +802,6 @@ static MMAL_STATUS_T mmal_vc_component_destroy(MMAL_COMPONENT_T *component)
|
||||
fail:
|
||||
// no longer require videocore
|
||||
mmal_vc_release();
|
||||
mmal_vc_release_client_component(component);
|
||||
mmal_vc_shm_exit();
|
||||
mmal_vc_deinit();
|
||||
return status;
|
||||
@@ -940,17 +928,6 @@ MMAL_STATUS_T mmal_vc_get_core_stats(MMAL_CORE_STATISTICS_T *stats,
|
||||
return status;
|
||||
}
|
||||
|
||||
static void mmal_vc_copy_es_format_to_vc(MMAL_ES_FORMAT_T *src, MMAL_VC_ES_FORMAT_T *dest)
|
||||
{
|
||||
// IPC MMAL_VC_ES_FORMAT_T is not necessarily the same as MMAL_ES_FORMAT_T,
|
||||
// so copy fields individually.
|
||||
dest->type = src->type;
|
||||
dest->encoding = src->encoding;
|
||||
dest->encoding_variant = src->encoding_variant;
|
||||
dest->bitrate = src->bitrate;
|
||||
dest->flags = src->flags;
|
||||
dest->extradata_size = src->extradata_size;
|
||||
}
|
||||
|
||||
/** Get port context data. */
|
||||
static MMAL_STATUS_T mmal_vc_port_info_get(MMAL_PORT_T *port)
|
||||
@@ -992,9 +969,9 @@ static MMAL_STATUS_T mmal_vc_port_info_get(MMAL_PORT_T *port)
|
||||
port->buffer_alignment_min = reply.port.buffer_alignment_min;
|
||||
port->is_enabled = reply.port.is_enabled;
|
||||
port->capabilities = reply.port.capabilities;
|
||||
|
||||
mmal_vc_copy_es_format_from_vc(&reply.format, port->format);
|
||||
|
||||
reply.format.extradata = port->format->extradata;
|
||||
reply.format.es = port->format->es;
|
||||
*port->format = reply.format;
|
||||
*port->format->es = reply.es;
|
||||
if(port->format->extradata_size)
|
||||
{
|
||||
@@ -1024,22 +1001,15 @@ static MMAL_STATUS_T mmal_vc_port_info_set(MMAL_PORT_T *port)
|
||||
msg.component_handle = module->component_handle;
|
||||
msg.port_type = port->type;
|
||||
msg.index = port->index;
|
||||
|
||||
//Only copy the values that are used into the MMAL_PORT_T of the IPC.
|
||||
msg.port.buffer_num = port->buffer_num;
|
||||
msg.port.buffer_size = port->buffer_size;
|
||||
msg.port.is_enabled = port->is_enabled;
|
||||
|
||||
mmal_vc_copy_es_format_to_vc(port->format, &msg.format);
|
||||
|
||||
msg.port = *port;
|
||||
msg.format = *port->format;
|
||||
msg.es = *port->format->es;
|
||||
|
||||
if(msg.format.extradata_size > MMAL_FORMAT_EXTRADATA_MAX_SIZE)
|
||||
{
|
||||
vcos_assert(0);
|
||||
msg.format.extradata_size = MMAL_FORMAT_EXTRADATA_MAX_SIZE;
|
||||
}
|
||||
memcpy(msg.extradata, port->format->extradata, msg.format.extradata_size);
|
||||
memcpy(msg.extradata, msg.format.extradata, msg.format.extradata_size);
|
||||
|
||||
LOG_TRACE("set port info (%i:%i)", port->type, port->index);
|
||||
|
||||
@@ -1067,9 +1037,9 @@ static MMAL_STATUS_T mmal_vc_port_info_set(MMAL_PORT_T *port)
|
||||
port->buffer_alignment_min = reply.port.buffer_alignment_min;
|
||||
port->is_enabled = reply.port.is_enabled;
|
||||
port->capabilities = reply.port.capabilities;
|
||||
|
||||
mmal_vc_copy_es_format_from_vc(&reply.format, port->format);
|
||||
|
||||
reply.format.extradata = port->format->extradata;
|
||||
reply.format.es = port->format->es;
|
||||
*port->format = reply.format;
|
||||
*port->format->es = reply.es;
|
||||
if(port->format->extradata_size)
|
||||
{
|
||||
@@ -1358,6 +1328,7 @@ static MMAL_STATUS_T mmal_vc_component_create(const char *name, MMAL_COMPONENT_T
|
||||
return MMAL_EINVAL;
|
||||
}
|
||||
|
||||
msg.client_component = component;
|
||||
/* coverity[secure_coding] Length tested above */
|
||||
strcpy(msg.name, basename);
|
||||
#ifdef __linux__
|
||||
@@ -1380,8 +1351,6 @@ static MMAL_STATUS_T mmal_vc_component_create(const char *name, MMAL_COMPONENT_T
|
||||
return status;
|
||||
}
|
||||
|
||||
msg.client_component = mmal_vc_allocate_client_component(component);
|
||||
|
||||
// claim VC for entire duration of component.
|
||||
status = mmal_vc_use();
|
||||
|
||||
@@ -1402,7 +1371,6 @@ static MMAL_STATUS_T mmal_vc_component_create(const char *name, MMAL_COMPONENT_T
|
||||
LOG_ERROR("failed to create component '%s' (%i:%s)", name, status,
|
||||
mmal_status_to_string(status));
|
||||
mmal_vc_release();
|
||||
mmal_vc_release_client_component(component);
|
||||
mmal_vc_shm_exit();
|
||||
mmal_vc_deinit();
|
||||
return status;
|
||||
@@ -1423,7 +1391,6 @@ static MMAL_STATUS_T mmal_vc_component_create(const char *name, MMAL_COMPONENT_T
|
||||
MMAL_WORKER_COMPONENT_DESTROY, &reply, &replylen, MMAL_FALSE);
|
||||
vcos_assert(destroy_status == MMAL_SUCCESS);
|
||||
mmal_vc_release();
|
||||
mmal_vc_release_client_component(component);
|
||||
mmal_vc_shm_exit();
|
||||
mmal_vc_deinit();
|
||||
return status;
|
||||
@@ -1529,7 +1496,6 @@ static MMAL_STATUS_T mmal_vc_component_create(const char *name, MMAL_COMPONENT_T
|
||||
module->event_ctx_initialised = MMAL_FALSE;
|
||||
module->event_ctx.magic = MMAL_MAGIC;
|
||||
module->event_ctx.callback_event = mmal_vc_port_send_event_callback;
|
||||
module->event_ctx_handle = mmal_vc_allocate_client_context(&module->event_ctx);
|
||||
|
||||
/* populate component structure */
|
||||
component->priv->pf_enable = mmal_vc_component_enable;
|
||||
|
||||
@@ -53,7 +53,6 @@ static VCOS_LOG_CAT_T mmal_ipc_log_category;
|
||||
*/
|
||||
typedef struct MMAL_WAITER_T
|
||||
{
|
||||
int index;
|
||||
VCOS_SEMAPHORE_T sem;
|
||||
unsigned inuse;
|
||||
void *dest; /**< Where to write reply */
|
||||
@@ -83,151 +82,6 @@ struct MMAL_CLIENT_T
|
||||
MMAL_BOOL_T inited;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Lookup table functions for client_component handles.
|
||||
* Required as the IPC is strictly 32bit, therefore 64bit userland can not
|
||||
* pass in the required pointers.
|
||||
*****************************************************************************/
|
||||
#define MAX_COMPONENT_HANDLES 128
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int inuse:1;
|
||||
unsigned int index:31;
|
||||
MMAL_COMPONENT_T *component;
|
||||
} MMAL_CLIENT_COMPONENT_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MMAL_CLIENT_COMPONENT_T components[MAX_COMPONENT_HANDLES];
|
||||
VCOS_MUTEX_T lock;
|
||||
} MMAL_CLIENT_COMPONENT_POOL_T;
|
||||
|
||||
static MMAL_CLIENT_COMPONENT_POOL_T client_component_pool;
|
||||
|
||||
uint32_t mmal_vc_allocate_client_component(MMAL_COMPONENT_T *component)
|
||||
{
|
||||
int i;
|
||||
|
||||
vcos_mutex_lock(&client_component_pool.lock);
|
||||
for (i=0; i<MAX_COMPONENT_HANDLES; i++)
|
||||
{
|
||||
if (client_component_pool.components[i].inuse == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (vcos_verify(i != MAX_COMPONENT_HANDLES))
|
||||
{
|
||||
client_component_pool.components[i].index = i;
|
||||
client_component_pool.components[i].component = component;
|
||||
client_component_pool.components[i].inuse = 1;
|
||||
}
|
||||
vcos_mutex_unlock(&client_component_pool.lock);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static MMAL_COMPONENT_T *lookup_client_component(int index)
|
||||
{
|
||||
if (vcos_verify(index < MAX_COMPONENT_HANDLES))
|
||||
{
|
||||
vcos_assert(client_component_pool.components[index].inuse);
|
||||
return client_component_pool.components[index].component;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mmal_vc_release_client_component(MMAL_COMPONENT_T *component)
|
||||
{
|
||||
int i;
|
||||
|
||||
vcos_mutex_lock(&client_component_pool.lock);
|
||||
for (i=0; i<MAX_COMPONENT_HANDLES; i++)
|
||||
{
|
||||
if (client_component_pool.components[i].component == component)
|
||||
{
|
||||
client_component_pool.components[i].component = NULL;
|
||||
client_component_pool.components[i].inuse = 0;
|
||||
}
|
||||
}
|
||||
vcos_mutex_unlock(&client_component_pool.lock);
|
||||
}
|
||||
|
||||
#define MAX_CLIENT_CONTEXTS 512
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int inuse:1;
|
||||
unsigned int index:31;
|
||||
MMAL_VC_CLIENT_BUFFER_CONTEXT_T *ctx;
|
||||
} MMAL_CLIENT_CONTEXT_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MMAL_CLIENT_CONTEXT_T contexts[MAX_CLIENT_CONTEXTS];
|
||||
VCOS_MUTEX_T lock;
|
||||
} MMAL_CLIENT_CONTEXT_POOL_T;
|
||||
|
||||
static MMAL_CLIENT_CONTEXT_POOL_T client_context_pool;
|
||||
#define CLIENT_CONTEXT_MAGIC 0xFEDC0000
|
||||
#define CLIENT_CONTEXT_MAGIC_MASK(a) (a & 0xFFFF)
|
||||
#define CLIENT_CONTEXT_MAGIC_CHECK(a) (a & 0xFFFF0000)
|
||||
|
||||
uint32_t mmal_vc_allocate_client_context(MMAL_VC_CLIENT_BUFFER_CONTEXT_T *context)
|
||||
{
|
||||
int i;
|
||||
|
||||
vcos_mutex_lock(&client_context_pool.lock);
|
||||
for (i=0; i<MAX_CLIENT_CONTEXTS; i++)
|
||||
{
|
||||
if (client_context_pool.contexts[i].inuse == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (vcos_verify(i != MAX_CLIENT_CONTEXTS))
|
||||
{
|
||||
client_context_pool.contexts[i].index = i;
|
||||
client_context_pool.contexts[i].ctx = context;
|
||||
client_context_pool.contexts[i].inuse = 1;
|
||||
}
|
||||
vcos_mutex_unlock(&client_context_pool.lock);
|
||||
|
||||
return i | CLIENT_CONTEXT_MAGIC;
|
||||
}
|
||||
|
||||
MMAL_VC_CLIENT_BUFFER_CONTEXT_T *mmal_vc_lookup_client_context(int index)
|
||||
{
|
||||
if (vcos_verify((CLIENT_CONTEXT_MAGIC_CHECK(index) == CLIENT_CONTEXT_MAGIC) &&
|
||||
(CLIENT_CONTEXT_MAGIC_MASK(index) < MAX_CLIENT_CONTEXTS)))
|
||||
{
|
||||
vcos_assert(client_context_pool.contexts[CLIENT_CONTEXT_MAGIC_MASK(index)].inuse);
|
||||
return client_context_pool.contexts[CLIENT_CONTEXT_MAGIC_MASK(index)].ctx;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mmal_vc_release_client_context(MMAL_VC_CLIENT_BUFFER_CONTEXT_T *context)
|
||||
{
|
||||
int i;
|
||||
|
||||
vcos_mutex_lock(&client_context_pool.lock);
|
||||
for (i=0; i<MAX_CLIENT_CONTEXTS; i++)
|
||||
{
|
||||
if (client_context_pool.contexts[i].ctx == context)
|
||||
{
|
||||
client_context_pool.contexts[i].ctx = NULL;
|
||||
client_context_pool.contexts[i].inuse = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= MAX_CLIENT_CONTEXTS)
|
||||
LOG_ERROR("Failed to release context %p - not found", context);
|
||||
|
||||
vcos_mutex_unlock(&client_context_pool.lock);
|
||||
}
|
||||
|
||||
/* One client per process/VC connection. Multiple threads may
|
||||
* be using a single client.
|
||||
*/
|
||||
@@ -236,8 +90,6 @@ static MMAL_CLIENT_T client;
|
||||
static void init_once(void)
|
||||
{
|
||||
vcos_mutex_create(&client.lock, VCOS_FUNCTION);
|
||||
vcos_mutex_create(&client_component_pool.lock, VCOS_FUNCTION);
|
||||
vcos_mutex_create(&client_context_pool.lock, VCOS_FUNCTION);
|
||||
}
|
||||
|
||||
/** Create a pool of wait-structures.
|
||||
@@ -255,7 +107,6 @@ static MMAL_STATUS_T create_waitpool(MMAL_WAITPOOL_T *waitpool)
|
||||
for (i=0; i<MAX_WAITERS; i++)
|
||||
{
|
||||
waitpool->waiters[i].inuse = 0;
|
||||
waitpool->waiters[i].index = i;
|
||||
status = vcos_semaphore_create(&waitpool->waiters[i].sem,
|
||||
"mmal waiter", 0);
|
||||
if (status != VCOS_SUCCESS)
|
||||
@@ -310,19 +161,6 @@ static MMAL_WAITER_T *get_waiter(MMAL_CLIENT_T *client)
|
||||
return waiter;
|
||||
}
|
||||
|
||||
/** Look up a waiter reference based on the static client
|
||||
*/
|
||||
static MMAL_WAITER_T *lookup_waiter(uint32_t index)
|
||||
{
|
||||
//NB this uses the static client variable, whilst most others use the client
|
||||
//variable passed in. I don't believe there is a way to have multiple clients
|
||||
//in one process, so this should be safe.
|
||||
if (vcos_verify(index < MAX_WAITERS))
|
||||
return &client.waitpool.waiters[index];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Return a waiter to the pool.
|
||||
*/
|
||||
static void release_waiter(MMAL_CLIENT_T *client, MMAL_WAITER_T *waiter)
|
||||
@@ -360,15 +198,13 @@ static void mmal_vc_handle_event_msg(VCHIQ_HEADER_T *vchiq_header,
|
||||
void *context)
|
||||
{
|
||||
mmal_worker_event_to_host *msg = (mmal_worker_event_to_host *)vchiq_header->data;
|
||||
MMAL_COMPONENT_T *component = lookup_client_component(msg->client_component);
|
||||
MMAL_VC_CLIENT_BUFFER_CONTEXT_T *client_context;
|
||||
MMAL_COMPONENT_T *component = msg->client_component;
|
||||
MMAL_BUFFER_HEADER_T *buffer;
|
||||
MMAL_STATUS_T status;
|
||||
MMAL_PORT_T *port;
|
||||
|
||||
LOG_DEBUG("event to host, cmd 0x%08x len %d to component %u/%p port (%d,%d)",
|
||||
msg->cmd, msg->length, msg->client_component, component, msg->port_type,
|
||||
msg->port_num);
|
||||
LOG_DEBUG("event to host, cmd 0x%08x len %d to component %p port (%d,%d)",
|
||||
msg->cmd, msg->length, msg->client_component, msg->port_type, msg->port_num);
|
||||
(void)context;
|
||||
|
||||
port = mmal_vc_port_by_number(component, msg->port_type, msg->port_num);
|
||||
@@ -393,12 +229,11 @@ static void mmal_vc_handle_event_msg(VCHIQ_HEADER_T *vchiq_header,
|
||||
}
|
||||
buffer->length = msg->length;
|
||||
|
||||
client_context = mmal_vc_lookup_client_context(mmal_buffer_header_driver_data(buffer)->client_context);
|
||||
/* Sanity check that the event buffers have the proper vc client context */
|
||||
if (!vcos_verify(mmal_buffer_header_driver_data(buffer)->magic == MMAL_MAGIC &&
|
||||
client_context &&
|
||||
client_context->magic == MMAL_MAGIC &&
|
||||
client_context->callback_event))
|
||||
mmal_buffer_header_driver_data(buffer)->client_context &&
|
||||
mmal_buffer_header_driver_data(buffer)->client_context->magic == MMAL_MAGIC &&
|
||||
mmal_buffer_header_driver_data(buffer)->client_context->callback_event))
|
||||
{
|
||||
LOG_ERROR("event buffers not configured properly by component");
|
||||
goto error;
|
||||
@@ -423,53 +258,9 @@ static void mmal_vc_handle_event_msg(VCHIQ_HEADER_T *vchiq_header,
|
||||
else
|
||||
{
|
||||
if (msg->length)
|
||||
{
|
||||
if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED && buffer->length >= msg->length)
|
||||
{
|
||||
//64bit userspace.
|
||||
//No need to fix the pointers in the msg as mmal_event_format_changed_get
|
||||
//will do that for us, but the start positions of each section does need
|
||||
//to be adjusted.
|
||||
mmal_worker_event_format_changed *fmt_changed_vc =
|
||||
(mmal_worker_event_format_changed*)msg->data;
|
||||
MMAL_EVENT_FORMAT_CHANGED_T *fmt_changed_host =
|
||||
(MMAL_EVENT_FORMAT_CHANGED_T*)buffer->data;
|
||||
MMAL_ES_FORMAT_T *fmt_host;
|
||||
MMAL_VC_ES_FORMAT_T *fmt_vc;
|
||||
MMAL_ES_SPECIFIC_FORMAT_T *es_host, *es_vc;
|
||||
const uint32_t size_host = sizeof(MMAL_EVENT_FORMAT_CHANGED_T) +
|
||||
sizeof(MMAL_ES_FORMAT_T) +
|
||||
sizeof(MMAL_ES_SPECIFIC_FORMAT_T);
|
||||
const uint32_t size_vc = sizeof(mmal_worker_event_format_changed) +
|
||||
sizeof(MMAL_VC_ES_FORMAT_T) +
|
||||
sizeof(MMAL_ES_SPECIFIC_FORMAT_T);
|
||||
memcpy(buffer->data, msg->data, msg->length);
|
||||
|
||||
//Copy the base event (ignore the format pointer from the end)
|
||||
memcpy(fmt_changed_host, fmt_changed_vc, sizeof(mmal_worker_event_format_changed));
|
||||
fmt_changed_host->format = NULL;
|
||||
|
||||
//Copy the es format
|
||||
fmt_vc = (MMAL_VC_ES_FORMAT_T *)&fmt_changed_vc[1];
|
||||
fmt_host = (MMAL_ES_FORMAT_T *)&fmt_changed_host[1];
|
||||
mmal_vc_copy_es_format_from_vc(fmt_vc, fmt_host);
|
||||
|
||||
//Copy the ES_SPECIFIC_FORMAT_T (structures are identical)
|
||||
es_host = (MMAL_ES_SPECIFIC_FORMAT_T *)&fmt_host[1];
|
||||
es_vc = (MMAL_ES_SPECIFIC_FORMAT_T *)&fmt_vc[1];
|
||||
memcpy(es_host, es_vc, sizeof(MMAL_ES_SPECIFIC_FORMAT_T));
|
||||
|
||||
//Copy the extradata (if present)
|
||||
fmt_host->extradata_size = msg->length - size_vc;
|
||||
memcpy((uint8_t *)&es_host[1], (uint8_t*)&es_vc[1], fmt_host->extradata_size);
|
||||
buffer->length = size_host + fmt_host->extradata_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(buffer->data, msg->data, msg->length);
|
||||
}
|
||||
}
|
||||
|
||||
client_context->callback_event(port, buffer);
|
||||
mmal_buffer_header_driver_data(buffer)->client_context->callback_event(port, buffer);
|
||||
LOG_DEBUG("done callback back to client");
|
||||
vchiq_release_message(service, vchiq_header);
|
||||
}
|
||||
@@ -533,36 +324,29 @@ static VCHIQ_STATUS_T mmal_vc_vchiq_callback(VCHIQ_REASON_T reason,
|
||||
|
||||
if (msg->msgid == MMAL_WORKER_BUFFER_TO_HOST)
|
||||
{
|
||||
MMAL_VC_CLIENT_BUFFER_CONTEXT_T *client_context;
|
||||
LOG_TRACE("buffer to host");
|
||||
mmal_worker_buffer_from_host *msg = (mmal_worker_buffer_from_host *)vchiq_header->data;
|
||||
|
||||
client_context = mmal_vc_lookup_client_context(msg->drvbuf.client_context);
|
||||
LOG_TRACE("len %d context %p", msg->buffer_header.length, client_context);
|
||||
vcos_assert(client_context);
|
||||
vcos_assert(client_context->magic == MMAL_MAGIC);
|
||||
LOG_TRACE("len %d context %p", msg->buffer_header.length, msg->drvbuf.client_context);
|
||||
vcos_assert(msg->drvbuf.client_context);
|
||||
vcos_assert(msg->drvbuf.client_context->magic == MMAL_MAGIC);
|
||||
|
||||
/* If the buffer is referencing another, need to replicate it here
|
||||
* in order to use the reference buffer's payload and ensure the
|
||||
* reference is not released prematurely */
|
||||
if (msg->has_reference)
|
||||
{
|
||||
MMAL_VC_CLIENT_BUFFER_CONTEXT_T *ref_context =
|
||||
mmal_vc_lookup_client_context(msg->drvbuf_ref.client_context);
|
||||
vcos_assert(ref_context);
|
||||
mmal_buffer_header_replicate(client_context->buffer, ref_context->buffer);
|
||||
}
|
||||
mmal_buffer_header_replicate(msg->drvbuf.client_context->buffer,
|
||||
msg->drvbuf_ref.client_context->buffer);
|
||||
|
||||
/* Sanity check the size of the transfer so we don't overrun our buffer */
|
||||
if (!vcos_verify(msg->buffer_header.offset + msg->buffer_header.length <=
|
||||
client_context->buffer->alloc_size))
|
||||
msg->drvbuf.client_context->buffer->alloc_size))
|
||||
{
|
||||
LOG_TRACE("buffer too small (%i, %i)",
|
||||
msg->buffer_header.offset + msg->buffer_header.length,
|
||||
client_context->buffer->alloc_size);
|
||||
msg->drvbuf.client_context->buffer->alloc_size);
|
||||
msg->buffer_header.length = 0;
|
||||
msg->buffer_header.flags |= MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED;
|
||||
client_context->callback(msg);
|
||||
msg->drvbuf.client_context->callback(msg);
|
||||
vchiq_release_message(service, vchiq_header);
|
||||
break;
|
||||
}
|
||||
@@ -573,7 +357,7 @@ static VCHIQ_STATUS_T mmal_vc_vchiq_callback(VCHIQ_REASON_T reason,
|
||||
{
|
||||
/* a buffer full of data for us to process */
|
||||
VCHIQ_STATUS_T vst = VCHIQ_SUCCESS;
|
||||
LOG_TRACE("queue bulk rx: %p, %d", client_context->buffer->data +
|
||||
LOG_TRACE("queue bulk rx: %p, %d", msg->drvbuf.client_context->buffer->data +
|
||||
msg->buffer_header.offset, msg->buffer_header.length);
|
||||
int len = msg->buffer_header.length;
|
||||
len = (len+3) & (~3);
|
||||
@@ -586,7 +370,7 @@ static VCHIQ_STATUS_T mmal_vc_vchiq_callback(VCHIQ_REASON_T reason,
|
||||
{
|
||||
/* buffer transferred using vchiq bulk xfer */
|
||||
vst = vchiq_queue_bulk_receive(service,
|
||||
client_context->buffer->data + msg->buffer_header.offset,
|
||||
msg->drvbuf.client_context->buffer->data + msg->buffer_header.offset,
|
||||
len, vchiq_header);
|
||||
|
||||
if (vst != VCHIQ_SUCCESS)
|
||||
@@ -594,20 +378,20 @@ static VCHIQ_STATUS_T mmal_vc_vchiq_callback(VCHIQ_REASON_T reason,
|
||||
LOG_TRACE("queue bulk rx len %d failed to start", msg->buffer_header.length);
|
||||
msg->buffer_header.length = 0;
|
||||
msg->buffer_header.flags |= MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED;
|
||||
client_context->callback(msg);
|
||||
msg->drvbuf.client_context->callback(msg);
|
||||
vchiq_release_message(service, vchiq_header);
|
||||
}
|
||||
}
|
||||
else if (msg->payload_in_message <= MMAL_VC_SHORT_DATA)
|
||||
{
|
||||
/* we have already received the buffer data in the message! */
|
||||
MMAL_BUFFER_HEADER_T *dst = client_context->buffer;
|
||||
MMAL_BUFFER_HEADER_T *dst = msg->drvbuf.client_context->buffer;
|
||||
LOG_TRACE("short data: dst = %p, dst->data = %p, len %d short len %d", dst, dst? dst->data : 0, msg->buffer_header.length, msg->payload_in_message);
|
||||
memcpy(dst->data, msg->short_data, msg->payload_in_message);
|
||||
dst->offset = 0;
|
||||
dst->length = msg->payload_in_message;
|
||||
vchiq_release_message(service, vchiq_header);
|
||||
client_context->callback(msg);
|
||||
msg->drvbuf.client_context->callback(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -625,9 +409,9 @@ static VCHIQ_STATUS_T mmal_vc_vchiq_callback(VCHIQ_REASON_T reason,
|
||||
* be picked up in the callback to complete the sequence.
|
||||
*/
|
||||
LOG_TRACE("doing cb (%p) context %p",
|
||||
client_context, client_context ?
|
||||
client_context->callback : 0);
|
||||
client_context->callback(msg);
|
||||
msg->drvbuf.client_context, msg->drvbuf.client_context ?
|
||||
msg->drvbuf.client_context->callback : 0);
|
||||
msg->drvbuf.client_context->callback(msg);
|
||||
LOG_TRACE("done callback back to client");
|
||||
vchiq_release_message(service, vchiq_header);
|
||||
}
|
||||
@@ -638,7 +422,7 @@ static VCHIQ_STATUS_T mmal_vc_vchiq_callback(VCHIQ_REASON_T reason,
|
||||
}
|
||||
else
|
||||
{
|
||||
MMAL_WAITER_T *waiter = lookup_waiter(msg->u.waiter);
|
||||
MMAL_WAITER_T *waiter = msg->u.waiter;
|
||||
LOG_TRACE("waking up waiter at %p", waiter);
|
||||
vcos_assert(waiter->inuse);
|
||||
int len = vcos_min(waiter->destlen, vchiq_header->size);
|
||||
@@ -659,7 +443,7 @@ static VCHIQ_STATUS_T mmal_vc_vchiq_callback(VCHIQ_REASON_T reason,
|
||||
#ifdef VCOS_LOGGING_ENABLED
|
||||
mmal_worker_buffer_from_host *msg = (mmal_worker_buffer_from_host *)context;
|
||||
#endif
|
||||
LOG_TRACE("bulk tx done: %08x, %d", msg->buffer_header.data, msg->buffer_header.length);
|
||||
LOG_TRACE("bulk tx done: %p, %d", msg->buffer_header.data, msg->buffer_header.length);
|
||||
}
|
||||
break;
|
||||
case VCHIQ_BULK_RECEIVE_DONE:
|
||||
@@ -669,21 +453,18 @@ static VCHIQ_STATUS_T mmal_vc_vchiq_callback(VCHIQ_REASON_T reason,
|
||||
if (msg_hdr->msgid == MMAL_WORKER_BUFFER_TO_HOST)
|
||||
{
|
||||
mmal_worker_buffer_from_host *msg = (mmal_worker_buffer_from_host *)msg_hdr;
|
||||
MMAL_VC_CLIENT_BUFFER_CONTEXT_T *client_context = mmal_vc_lookup_client_context(msg->drvbuf.client_context);
|
||||
vcos_assert(client_context && client_context->magic == MMAL_MAGIC);
|
||||
client_context->callback(msg);
|
||||
LOG_TRACE("bulk rx done: %08x, %d", msg->buffer_header.data, msg->buffer_header.length);
|
||||
vcos_assert(msg->drvbuf.client_context->magic == MMAL_MAGIC);
|
||||
msg->drvbuf.client_context->callback(msg);
|
||||
LOG_TRACE("bulk rx done: %p, %d", msg->buffer_header.data, msg->buffer_header.length);
|
||||
}
|
||||
else
|
||||
{
|
||||
mmal_worker_event_to_host *msg = (mmal_worker_event_to_host *)msg_hdr;
|
||||
MMAL_COMPONENT_T *component = lookup_client_component(msg->client_component);
|
||||
MMAL_VC_CLIENT_BUFFER_CONTEXT_T *client_context =
|
||||
mmal_vc_lookup_client_context(mmal_buffer_header_driver_data(msg->delayed_buffer)->client_context);
|
||||
MMAL_PORT_T *port = mmal_vc_port_by_number(component, msg->port_type, msg->port_num);
|
||||
MMAL_PORT_T *port = mmal_vc_port_by_number(msg->client_component, msg->port_type, msg->port_num);
|
||||
|
||||
vcos_assert(client_context && port);
|
||||
client_context->callback_event(port, msg->delayed_buffer);
|
||||
vcos_assert(port);
|
||||
mmal_buffer_header_driver_data(msg->delayed_buffer)->
|
||||
client_context->callback_event(port, msg->delayed_buffer);
|
||||
LOG_DEBUG("event bulk rx done, length %d", msg->length);
|
||||
}
|
||||
vchiq_release_message(service, header);
|
||||
@@ -696,25 +477,21 @@ static VCHIQ_STATUS_T mmal_vc_vchiq_callback(VCHIQ_REASON_T reason,
|
||||
if (msg_hdr->msgid == MMAL_WORKER_BUFFER_TO_HOST)
|
||||
{
|
||||
mmal_worker_buffer_from_host *msg = (mmal_worker_buffer_from_host *)msg_hdr;
|
||||
MMAL_VC_CLIENT_BUFFER_CONTEXT_T *client_context = mmal_vc_lookup_client_context(msg->drvbuf.client_context);
|
||||
LOG_TRACE("bulk rx aborted: %08x, %d", msg->buffer_header.data, msg->buffer_header.length);
|
||||
vcos_assert(client_context && client_context->magic == MMAL_MAGIC);
|
||||
LOG_TRACE("bulk rx aborted: %p, %d", msg->buffer_header.data, msg->buffer_header.length);
|
||||
vcos_assert(msg->drvbuf.client_context->magic == MMAL_MAGIC);
|
||||
msg->buffer_header.flags |= MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED;
|
||||
client_context->callback(msg);
|
||||
msg->drvbuf.client_context->callback(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
mmal_worker_event_to_host *msg = (mmal_worker_event_to_host *)msg_hdr;
|
||||
MMAL_COMPONENT_T *component = lookup_client_component(msg->client_component);
|
||||
MMAL_VC_CLIENT_BUFFER_CONTEXT_T *client_context =
|
||||
mmal_vc_lookup_client_context(mmal_buffer_header_driver_data(msg->delayed_buffer)->client_context);
|
||||
MMAL_PORT_T *port = mmal_vc_port_by_number(component, msg->port_type, msg->port_num);
|
||||
MMAL_PORT_T *port = mmal_vc_port_by_number(msg->client_component, msg->port_type, msg->port_num);
|
||||
|
||||
vcos_assert(port);
|
||||
LOG_DEBUG("event bulk rx aborted");
|
||||
msg->delayed_buffer->flags |= MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED;
|
||||
|
||||
client_context->callback_event(port, msg->delayed_buffer);
|
||||
mmal_buffer_header_driver_data(msg->delayed_buffer)->
|
||||
client_context->callback_event(port, msg->delayed_buffer);
|
||||
}
|
||||
vchiq_release_message(service, header);
|
||||
}
|
||||
@@ -722,12 +499,9 @@ static VCHIQ_STATUS_T mmal_vc_vchiq_callback(VCHIQ_REASON_T reason,
|
||||
case VCHIQ_BULK_TRANSMIT_ABORTED:
|
||||
{
|
||||
mmal_worker_buffer_from_host *msg = (mmal_worker_buffer_from_host *)context;
|
||||
MMAL_VC_CLIENT_BUFFER_CONTEXT_T *client_context =
|
||||
mmal_vc_lookup_client_context(msg->drvbuf.client_context);
|
||||
LOG_INFO("bulk tx aborted: %08x, %d", msg->buffer_header.data, msg->buffer_header.length);
|
||||
vcos_assert(client_context->magic == MMAL_MAGIC);
|
||||
LOG_INFO("bulk tx aborted: %p, %d", msg->buffer_header.data, msg->buffer_header.length);
|
||||
vcos_assert(msg->drvbuf.client_context->magic == MMAL_MAGIC);
|
||||
/* Nothing to do as the VC side will release the buffer and notify us of the error */
|
||||
client_context = NULL; // Avoid warnings in release builds
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -774,7 +548,7 @@ MMAL_STATUS_T mmal_vc_sendwait_message(struct MMAL_CLIENT_T *client,
|
||||
|
||||
waiter = get_waiter(client);
|
||||
msg_header->msgid = msgid;
|
||||
msg_header->u.waiter = waiter->index;
|
||||
msg_header->u.waiter = waiter;
|
||||
msg_header->magic = MMAL_MAGIC;
|
||||
|
||||
waiter->dest = dest;
|
||||
|
||||
@@ -76,11 +76,5 @@ MMAL_STATUS_T mmal_vc_send_message(MMAL_CLIENT_T *client,
|
||||
uint8_t *data, size_t data_size,
|
||||
uint32_t msgid);
|
||||
|
||||
uint32_t mmal_vc_allocate_client_component(MMAL_COMPONENT_T *component);
|
||||
void mmal_vc_release_client_component(MMAL_COMPONENT_T *component);
|
||||
|
||||
uint32_t mmal_vc_allocate_client_context(MMAL_VC_CLIENT_BUFFER_CONTEXT_T *context);
|
||||
MMAL_VC_CLIENT_BUFFER_CONTEXT_T *mmal_vc_lookup_client_context(int index);
|
||||
void mmal_vc_release_client_context(MMAL_VC_CLIENT_BUFFER_CONTEXT_T *context);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -112,10 +112,10 @@ typedef struct
|
||||
{
|
||||
uint32_t magic;
|
||||
uint32_t msgid;
|
||||
uint32_t control_service; /** Handle to the control service (unused) */
|
||||
struct MMAL_CONTROL_SERVICE_T *control_service; /** Handle to the control service */
|
||||
|
||||
union {
|
||||
uint32_t waiter; /** User-land wait structure, passed back */
|
||||
struct MMAL_WAITER_T *waiter; /** User-land wait structure, passed back */
|
||||
} u;
|
||||
|
||||
MMAL_STATUS_T status; /** Result code, passed back */
|
||||
@@ -152,7 +152,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
mmal_worker_msg_header header;
|
||||
uint32_t client_component; /** Client component */
|
||||
void *client_component; /** Client component */
|
||||
char name[128];
|
||||
uint32_t pid; /**< For debug */
|
||||
} mmal_worker_component_create;
|
||||
@@ -206,71 +206,6 @@ typedef struct
|
||||
} mmal_worker_port_info_get;
|
||||
vcos_static_assert(sizeof(mmal_worker_port_info_get) <= MMAL_WORKER_MAX_MSG_LEN);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MMAL_ES_TYPE_T type; /**< Type of the elementary stream */
|
||||
|
||||
MMAL_FOURCC_T encoding; /**< FourCC specifying the encoding of the elementary stream.
|
||||
* See the \ref MmalEncodings "pre-defined encodings" for some
|
||||
* examples.
|
||||
*/
|
||||
MMAL_FOURCC_T encoding_variant;/**< FourCC specifying the specific encoding variant of
|
||||
* the elementary stream. See the \ref MmalEncodingVariants
|
||||
* "pre-defined encoding variants" for some examples.
|
||||
*/
|
||||
|
||||
uint32_t es; /**< Type specific information for the elementary stream */
|
||||
|
||||
uint32_t bitrate; /**< Bitrate in bits per second */
|
||||
uint32_t flags; /**< Flags describing properties of the elementary stream.
|
||||
* See \ref elementarystreamflags "Elementary stream flags".
|
||||
*/
|
||||
|
||||
uint32_t extradata_size; /**< Size of the codec specific data */
|
||||
uint32_t extradata; /**< Codec specific data */
|
||||
|
||||
} MMAL_VC_ES_FORMAT_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t priv; /**< Private member used by the framework */
|
||||
uint32_t name; /**< Port name. Used for debugging purposes (Read Only) */
|
||||
|
||||
MMAL_PORT_TYPE_T type; /**< Type of the port (Read Only) */
|
||||
uint16_t index; /**< Index of the port in its type list (Read Only) */
|
||||
uint16_t index_all; /**< Index of the port in the list of all ports (Read Only) */
|
||||
|
||||
uint32_t is_enabled; /**< Indicates whether the port is enabled or not (Read Only) */
|
||||
uint32_t format; /**< Format of the elementary stream */
|
||||
|
||||
uint32_t buffer_num_min; /**< Minimum number of buffers the port requires (Read Only).
|
||||
This is set by the component. */
|
||||
uint32_t buffer_size_min; /**< Minimum size of buffers the port requires (Read Only).
|
||||
This is set by the component. */
|
||||
uint32_t buffer_alignment_min; /**< Minimum alignment requirement for the buffers (Read Only).
|
||||
A value of zero means no special alignment requirements.
|
||||
This is set by the component. */
|
||||
uint32_t buffer_num_recommended; /**< Number of buffers the port recommends for optimal performance (Read Only).
|
||||
A value of zero means no special recommendation.
|
||||
This is set by the component. */
|
||||
uint32_t buffer_size_recommended; /**< Size of buffers the port recommends for optimal performance (Read Only).
|
||||
A value of zero means no special recommendation.
|
||||
This is set by the component. */
|
||||
uint32_t buffer_num; /**< Actual number of buffers the port will use.
|
||||
This is set by the client. */
|
||||
uint32_t buffer_size; /**< Actual maximum size of the buffers that will be sent
|
||||
to the port. This is set by the client. */
|
||||
|
||||
uint32_t component; /**< Component this port belongs to (Read Only) */
|
||||
uint32_t userdata; /**< Field reserved for use by the client */
|
||||
|
||||
uint32_t capabilities; /**< Flags describing the capabilities of a port (Read Only).
|
||||
* Bitwise combination of \ref portcapabilities "Port capabilities"
|
||||
* values.
|
||||
*/
|
||||
|
||||
} MMAL_VC_PORT_T;
|
||||
|
||||
/** Component port info. Used to set port info.
|
||||
*/
|
||||
typedef struct
|
||||
@@ -279,8 +214,8 @@ typedef struct
|
||||
uint32_t component_handle; /**< Which component */
|
||||
MMAL_PORT_TYPE_T port_type; /**< Type of port */
|
||||
uint32_t index; /**< Which port of given type to get */
|
||||
MMAL_VC_PORT_T port;
|
||||
MMAL_VC_ES_FORMAT_T format;
|
||||
MMAL_PORT_T port;
|
||||
MMAL_ES_FORMAT_T format;
|
||||
MMAL_ES_SPECIFIC_FORMAT_T es;
|
||||
uint8_t extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE];
|
||||
} mmal_worker_port_info_set;
|
||||
@@ -296,8 +231,8 @@ typedef struct
|
||||
uint32_t index; /**< Which port of given type to get */
|
||||
int32_t found; /**< Did we find anything? */
|
||||
uint32_t port_handle; /**< Handle to use for this port */
|
||||
MMAL_VC_PORT_T port;
|
||||
MMAL_VC_ES_FORMAT_T format;
|
||||
MMAL_PORT_T port;
|
||||
MMAL_ES_FORMAT_T format;
|
||||
MMAL_ES_SPECIFIC_FORMAT_T es;
|
||||
uint8_t extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE];
|
||||
} mmal_worker_port_info;
|
||||
@@ -350,7 +285,7 @@ typedef struct
|
||||
/** Action parameter */
|
||||
union {
|
||||
struct {
|
||||
MMAL_VC_PORT_T port;
|
||||
MMAL_PORT_T port;
|
||||
} enable;
|
||||
struct {
|
||||
uint32_t component_handle;
|
||||
@@ -422,41 +357,9 @@ struct MMAL_DRIVER_BUFFER_T
|
||||
uint32_t port_handle; /**< Index into array of ports for this component */
|
||||
|
||||
/** Client side uses this to get back to its context structure. */
|
||||
uint32_t client_context;
|
||||
struct MMAL_VC_CLIENT_BUFFER_CONTEXT_T *client_context;
|
||||
};
|
||||
|
||||
typedef struct MMAL_VC_BUFFER_HEADER_T
|
||||
{
|
||||
uint32_t next; /**< Used to link several buffer headers together */
|
||||
|
||||
uint32_t priv; /**< Data private to the framework */
|
||||
|
||||
uint32_t cmd; /**< Defines what the buffer header contains. This is a FourCC
|
||||
with 0 as a special value meaning stream data */
|
||||
|
||||
uint32_t data; /**< Pointer to the start of the payload buffer (should not be
|
||||
changed by component) */
|
||||
uint32_t alloc_size; /**< Allocated size in bytes of payload buffer */
|
||||
uint32_t length; /**< Number of bytes currently used in the payload buffer (starting
|
||||
from offset) */
|
||||
uint32_t offset; /**< Offset in bytes to the start of valid data in the payload buffer */
|
||||
|
||||
uint32_t flags; /**< Flags describing properties of a buffer header (see
|
||||
\ref bufferheaderflags "Buffer header flags") */
|
||||
|
||||
int64_t pts; /**< Presentation timestamp in microseconds. \ref MMAL_TIME_UNKNOWN
|
||||
is used when the pts is unknown. */
|
||||
int64_t dts; /**< Decode timestamp in microseconds (dts = pts, except in the case
|
||||
of video streams with B frames). \ref MMAL_TIME_UNKNOWN
|
||||
is used when the dts is unknown. */
|
||||
|
||||
/** Type specific data that's associated with a payload buffer */
|
||||
uint32_t type;
|
||||
|
||||
uint32_t user_data; /**< Field reserved for use by the client */
|
||||
|
||||
} MMAL_VC_BUFFER_HEADER_T;
|
||||
|
||||
/** Receive a buffer from the host.
|
||||
*
|
||||
* @sa mmal_port_send_buffer()
|
||||
@@ -479,7 +382,7 @@ typedef struct mmal_worker_buffer_from_host
|
||||
struct MMAL_DRIVER_BUFFER_T drvbuf_ref;
|
||||
|
||||
/** the buffer header itself */
|
||||
MMAL_VC_BUFFER_HEADER_T buffer_header;
|
||||
MMAL_BUFFER_HEADER_T buffer_header;
|
||||
MMAL_BUFFER_HEADER_TYPE_SPECIFIC_T buffer_header_type_specific;
|
||||
|
||||
MMAL_BOOL_T is_zero_copy;
|
||||
@@ -508,29 +411,17 @@ typedef struct mmal_worker_event_to_host
|
||||
{
|
||||
mmal_worker_msg_header header;
|
||||
|
||||
uint32_t client_component;
|
||||
struct MMAL_COMPONENT_T *client_component;
|
||||
uint32_t port_type;
|
||||
uint32_t port_num;
|
||||
|
||||
uint32_t cmd;
|
||||
uint32_t length;
|
||||
uint8_t data[MMAL_WORKER_EVENT_SPACE];
|
||||
MMAL_BUFFER_HEADER_T *delayed_buffer; /* Only used to remember buffer for bulk rx */ // FIXME
|
||||
MMAL_BUFFER_HEADER_T *delayed_buffer; /* Only used to remember buffer for bulk rx */
|
||||
} mmal_worker_event_to_host;
|
||||
vcos_static_assert(sizeof(mmal_worker_event_to_host) <= MMAL_WORKER_MAX_MSG_LEN);
|
||||
|
||||
typedef struct mmal_worker_event_format_changed
|
||||
{
|
||||
uint32_t buffer_size_min; /**< Minimum size of buffers the port requires */
|
||||
uint32_t buffer_num_min; /**< Minimum number of buffers the port requires */
|
||||
uint32_t buffer_size_recommended; /**< Size of buffers the port recommends for optimal performance.
|
||||
A value of zero means no special recommendation. */
|
||||
uint32_t buffer_num_recommended; /**< Number of buffers the port recommends for optimal
|
||||
performance. A value of zero means no special recommendation. */
|
||||
|
||||
uint32_t format; /**< New elementary stream format */
|
||||
} mmal_worker_event_format_changed;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mmal_worker_msg_header header;
|
||||
@@ -624,7 +515,7 @@ static inline void mmal_vc_buffer_header_to_msg(mmal_worker_buffer_from_host *ms
|
||||
msg->buffer_header.pts = header->pts;
|
||||
msg->buffer_header.dts = header->dts;
|
||||
msg->buffer_header.alloc_size = header->alloc_size;
|
||||
msg->buffer_header.data = (uintptr_t)header->data;
|
||||
msg->buffer_header.data = header->data;
|
||||
msg->buffer_header_type_specific = *header->type;
|
||||
}
|
||||
|
||||
@@ -640,17 +531,5 @@ static inline void mmal_vc_msg_to_buffer_header(MMAL_BUFFER_HEADER_T *header,
|
||||
*header->type = msg->buffer_header_type_specific;
|
||||
}
|
||||
|
||||
static inline void mmal_vc_copy_es_format_from_vc(MMAL_VC_ES_FORMAT_T *src, MMAL_ES_FORMAT_T *dest)
|
||||
{
|
||||
// IPC MMAL_VC_ES_FORMAT_T is not necessarily the same as MMAL_ES_FORMAT_T,
|
||||
// so copy fields individually.
|
||||
dest->type = src->type;
|
||||
dest->encoding = src->encoding;
|
||||
dest->encoding_variant = src->encoding_variant;
|
||||
dest->bitrate = src->bitrate;
|
||||
dest->flags = src->flags;
|
||||
dest->extradata_size = src->extradata_size;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user