Änderungen Gruppe 30_10_2022 V2
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
add_library (mmal_util ${LIBRARY_TYPE}
|
||||
mmal_il.c
|
||||
mmal_util.c
|
||||
mmal_connection.c
|
||||
mmal_graph.c
|
||||
mmal_list.c
|
||||
mmal_param_convert.c
|
||||
mmal_util_params.c
|
||||
mmal_component_wrapper.c
|
||||
mmal_util_rational.c
|
||||
)
|
||||
|
||||
target_link_libraries (mmal_util vcos)
|
||||
|
||||
install(TARGETS mmal_util DESTINATION lib)
|
||||
install(FILES
|
||||
mmal_component_wrapper.h
|
||||
mmal_connection.h
|
||||
mmal_default_components.h
|
||||
mmal_graph.h
|
||||
mmal_il.h
|
||||
mmal_list.h
|
||||
mmal_param_convert.h
|
||||
mmal_util.h
|
||||
mmal_util_params.h
|
||||
mmal_util_rational.h
|
||||
DESTINATION include/interface/mmal/util
|
||||
)
|
||||
+368
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "mmal.h"
|
||||
#include "util/mmal_util.h"
|
||||
#include "util/mmal_component_wrapper.h"
|
||||
#include "mmal_logging.h"
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MMAL_WRAPPER_T wrapper; /**< Must be the first member! */
|
||||
|
||||
VCOS_SEMAPHORE_T sema;
|
||||
|
||||
} MMAL_WRAPPER_PRIVATE_T;
|
||||
|
||||
/** Callback from a control port. Error events will be received there. */
|
||||
static void mmal_wrapper_control_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
|
||||
{
|
||||
MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)port->userdata;
|
||||
LOG_TRACE("%s(%p),%p,%4.4s", port->name, port, buffer, (char *)&buffer->cmd);
|
||||
|
||||
if (buffer->cmd == MMAL_EVENT_ERROR)
|
||||
{
|
||||
private->wrapper.status = *(MMAL_STATUS_T *)buffer->data;
|
||||
mmal_buffer_header_release(buffer);
|
||||
|
||||
vcos_semaphore_post(&private->sema);
|
||||
|
||||
if (private->wrapper.callback)
|
||||
private->wrapper.callback(&private->wrapper);
|
||||
return;
|
||||
}
|
||||
|
||||
mmal_buffer_header_release(buffer);
|
||||
}
|
||||
|
||||
/** Callback from an input port. Buffer is released. */
|
||||
static void mmal_wrapper_bh_in_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
|
||||
{
|
||||
MMAL_PARAM_UNUSED(port);
|
||||
LOG_TRACE("(%s)%p,%p,%p,%i", port->name, port, buffer, buffer->data, (int)buffer->length);
|
||||
|
||||
/* We're done with the buffer, just recycle it */
|
||||
mmal_buffer_header_release(buffer);
|
||||
}
|
||||
|
||||
/** Callback from an output port. Buffer is queued for the next component. */
|
||||
static void mmal_wrapper_bh_out_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
|
||||
{
|
||||
MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)port->userdata;
|
||||
LOG_TRACE("(%s)%p,%p,%p,%i", port->name, port, buffer, buffer->data, (int)buffer->length);
|
||||
|
||||
/* Queue the buffer produced by the output port */
|
||||
mmal_queue_put(private->wrapper.output_queue[port->index], buffer);
|
||||
vcos_semaphore_post(&private->sema);
|
||||
|
||||
if (private->wrapper.callback)
|
||||
private->wrapper.callback(&private->wrapper);
|
||||
}
|
||||
|
||||
/** Callback from the pool. Buffer is available. */
|
||||
static MMAL_BOOL_T mmal_wrapper_bh_release_cb(MMAL_POOL_T *pool, MMAL_BUFFER_HEADER_T *buffer,
|
||||
void *userdata)
|
||||
{
|
||||
MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)userdata;
|
||||
|
||||
mmal_queue_put(pool->queue, buffer);
|
||||
vcos_semaphore_post(&private->sema);
|
||||
|
||||
if (private->wrapper.callback)
|
||||
private->wrapper.callback(&private->wrapper);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
MMAL_STATUS_T mmal_wrapper_destroy(MMAL_WRAPPER_T *wrapper)
|
||||
{
|
||||
MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)wrapper;
|
||||
unsigned int i;
|
||||
|
||||
LOG_TRACE("%p, %s", wrapper, wrapper->component->name);
|
||||
|
||||
/* Cleanup resources */
|
||||
mmal_component_destroy(wrapper->component);
|
||||
|
||||
for (i = 0; i < wrapper->input_num; i++)
|
||||
{
|
||||
if (wrapper->input_pool[i])
|
||||
mmal_pool_destroy(wrapper->input_pool[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < wrapper->output_num; i++)
|
||||
{
|
||||
if (wrapper->output_pool[i])
|
||||
mmal_pool_destroy(wrapper->output_pool[i]);
|
||||
if (wrapper->output_queue[i])
|
||||
mmal_queue_destroy(wrapper->output_queue[i]);
|
||||
}
|
||||
|
||||
vcos_semaphore_delete(&private->sema);
|
||||
vcos_free(private);
|
||||
return MMAL_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
MMAL_STATUS_T mmal_wrapper_create(MMAL_WRAPPER_T **ctx, const char *name)
|
||||
{
|
||||
MMAL_STATUS_T status;
|
||||
MMAL_COMPONENT_T *component;
|
||||
MMAL_WRAPPER_PRIVATE_T *private;
|
||||
MMAL_WRAPPER_T *wrapper;
|
||||
int64_t start_time;
|
||||
unsigned int i, extra_size;
|
||||
|
||||
LOG_TRACE("wrapper %p, name %s", ctx, name);
|
||||
|
||||
/* Sanity checking */
|
||||
if (!ctx || !name)
|
||||
return MMAL_EINVAL;
|
||||
|
||||
start_time = vcos_getmicrosecs();
|
||||
|
||||
status = mmal_component_create(name, &component);
|
||||
if (status != MMAL_SUCCESS)
|
||||
return status;
|
||||
|
||||
extra_size = (component->input_num + component->output_num) * 2;
|
||||
private = vcos_calloc(1, sizeof(*private) + extra_size, "mmal wrapper");
|
||||
if (!private)
|
||||
{
|
||||
mmal_component_destroy(component);
|
||||
return MMAL_ENOMEM;
|
||||
}
|
||||
|
||||
if (vcos_semaphore_create(&private->sema, "mmal wrapper", 0) != VCOS_SUCCESS)
|
||||
{
|
||||
mmal_component_destroy(component);
|
||||
vcos_free(private);
|
||||
return MMAL_ENOMEM;
|
||||
}
|
||||
|
||||
wrapper = &private->wrapper;
|
||||
wrapper->component = component;
|
||||
wrapper->control = component->control;
|
||||
wrapper->input_num = component->input_num;
|
||||
wrapper->input = component->input;
|
||||
wrapper->output_num = component->output_num;
|
||||
wrapper->output = component->output;
|
||||
wrapper->input_pool = (MMAL_POOL_T **)&private[1];
|
||||
wrapper->output_pool = (MMAL_POOL_T **)&wrapper->input_pool[component->input_num];
|
||||
wrapper->output_queue = (MMAL_QUEUE_T **)&wrapper->output_pool[component->output_num];
|
||||
|
||||
/* Create our pools and queues */
|
||||
for (i = 0; i < wrapper->input_num; i++)
|
||||
{
|
||||
wrapper->input_pool[i] = mmal_port_pool_create(wrapper->input[i], 0, 0);
|
||||
if (!wrapper->input_pool[i])
|
||||
goto error;
|
||||
mmal_pool_callback_set(wrapper->input_pool[i], mmal_wrapper_bh_release_cb, (void *)wrapper);
|
||||
|
||||
wrapper->input[i]->userdata = (void *)wrapper;
|
||||
}
|
||||
for (i = 0; i < wrapper->output_num; i++)
|
||||
{
|
||||
wrapper->output_pool[i] = mmal_port_pool_create(wrapper->output[i], 0, 0);
|
||||
wrapper->output_queue[i] = mmal_queue_create();
|
||||
if (!wrapper->output_pool[i] || !wrapper->output_queue[i])
|
||||
goto error;
|
||||
mmal_pool_callback_set(wrapper->output_pool[i], mmal_wrapper_bh_release_cb, (void *)wrapper);
|
||||
|
||||
wrapper->output[i]->userdata = (void *)wrapper;
|
||||
}
|
||||
|
||||
/* Setup control port */
|
||||
wrapper->control->userdata = (void *)wrapper;
|
||||
status = mmal_port_enable(wrapper->control, mmal_wrapper_control_cb);
|
||||
if (status != MMAL_SUCCESS)
|
||||
goto error;
|
||||
|
||||
wrapper->time_setup = vcos_getmicrosecs() - start_time;
|
||||
*ctx = wrapper;
|
||||
return MMAL_SUCCESS;
|
||||
|
||||
error:
|
||||
mmal_wrapper_destroy(wrapper);
|
||||
return status == MMAL_SUCCESS ? MMAL_ENOMEM : status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
MMAL_STATUS_T mmal_wrapper_port_enable(MMAL_PORT_T *port, uint32_t flags)
|
||||
{
|
||||
MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)port->userdata;
|
||||
MMAL_WRAPPER_T *wrapper = &private->wrapper;
|
||||
int64_t start_time = vcos_getmicrosecs();
|
||||
uint32_t buffer_size;
|
||||
MMAL_STATUS_T status;
|
||||
MMAL_POOL_T *pool;
|
||||
|
||||
LOG_TRACE("%p, %s", wrapper, port->name);
|
||||
|
||||
if (port->type != MMAL_PORT_TYPE_INPUT && port->type != MMAL_PORT_TYPE_OUTPUT)
|
||||
return MMAL_EINVAL;
|
||||
|
||||
if (port->is_enabled)
|
||||
return MMAL_SUCCESS;
|
||||
|
||||
pool = port->type == MMAL_PORT_TYPE_INPUT ?
|
||||
wrapper->input_pool[port->index] : wrapper->output_pool[port->index];
|
||||
buffer_size = (flags & MMAL_WRAPPER_FLAG_PAYLOAD_ALLOCATE) ? port->buffer_size : 0;
|
||||
|
||||
/* FIXME: we don't support switching between shared and non-shared memory.
|
||||
* We would need to save the flag and force a pool resize when switching. */
|
||||
if (flags & MMAL_WRAPPER_FLAG_PAYLOAD_USE_SHARED_MEMORY)
|
||||
{
|
||||
MMAL_PARAMETER_BOOLEAN_T param_zc =
|
||||
{{MMAL_PARAMETER_ZERO_COPY, sizeof(MMAL_PARAMETER_BOOLEAN_T)}, 1};
|
||||
status = mmal_port_parameter_set(port, ¶m_zc.hdr);
|
||||
if (status != MMAL_SUCCESS && status != MMAL_ENOSYS)
|
||||
{
|
||||
LOG_ERROR("failed to set zero copy on %s", port->name);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Resize the pool */
|
||||
status = mmal_pool_resize(pool, port->buffer_num, buffer_size);
|
||||
if (status != MMAL_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("could not resize pool (%i/%i)", (int)port->buffer_num, (int)buffer_size);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Enable port. The callback specified here is the function which
|
||||
* will be called when a buffer header comes back to the port. */
|
||||
status = mmal_port_enable(port, port->type == MMAL_PORT_TYPE_INPUT ?
|
||||
mmal_wrapper_bh_in_cb : mmal_wrapper_bh_out_cb);
|
||||
if (status != MMAL_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("could not enable port");
|
||||
return status;
|
||||
}
|
||||
|
||||
wrapper->time_enable += vcos_getmicrosecs() - start_time;
|
||||
return MMAL_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
MMAL_STATUS_T mmal_wrapper_port_disable(MMAL_PORT_T *port)
|
||||
{
|
||||
MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)port->userdata;
|
||||
MMAL_WRAPPER_T *wrapper = &private->wrapper;
|
||||
int64_t start_time = vcos_getmicrosecs();
|
||||
MMAL_STATUS_T status;
|
||||
|
||||
LOG_TRACE("%p, %s", wrapper, port->name);
|
||||
|
||||
if (port->type != MMAL_PORT_TYPE_INPUT && port->type != MMAL_PORT_TYPE_OUTPUT)
|
||||
return MMAL_EINVAL;
|
||||
|
||||
if (!port->is_enabled)
|
||||
return MMAL_SUCCESS;
|
||||
|
||||
/* Disable port */
|
||||
status = mmal_port_disable(port);
|
||||
if (status != MMAL_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("could not disable port");
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Flush the queue */
|
||||
if (port->type == MMAL_PORT_TYPE_OUTPUT)
|
||||
{
|
||||
MMAL_POOL_T *pool = wrapper->output_pool[port->index];
|
||||
MMAL_QUEUE_T *queue = wrapper->output_queue[port->index];
|
||||
MMAL_BUFFER_HEADER_T *buffer;
|
||||
|
||||
while ((buffer = mmal_queue_get(queue)) != NULL)
|
||||
mmal_buffer_header_release(buffer);
|
||||
|
||||
if ( !vcos_verify(mmal_queue_length(pool->queue) == pool->headers_num) )
|
||||
{
|
||||
LOG_ERROR("coul dnot release all buffers");
|
||||
}
|
||||
}
|
||||
|
||||
wrapper->time_disable = vcos_getmicrosecs() - start_time;
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Wait for an empty buffer to be available on a port */
|
||||
MMAL_STATUS_T mmal_wrapper_buffer_get_empty(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T **buffer,
|
||||
uint32_t flags)
|
||||
{
|
||||
MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)port->userdata;
|
||||
MMAL_WRAPPER_T *wrapper = &private->wrapper;
|
||||
MMAL_POOL_T *pool;
|
||||
|
||||
LOG_TRACE("%p, %s", wrapper, port->name);
|
||||
|
||||
if (!buffer || (port->type != MMAL_PORT_TYPE_INPUT && port->type != MMAL_PORT_TYPE_OUTPUT))
|
||||
return MMAL_EINVAL;
|
||||
|
||||
pool = port->type == MMAL_PORT_TYPE_INPUT ?
|
||||
wrapper->input_pool[port->index] : wrapper->output_pool[port->index];
|
||||
|
||||
while (wrapper->status == MMAL_SUCCESS &&
|
||||
(*buffer = mmal_queue_get(pool->queue)) == NULL)
|
||||
{
|
||||
if (!(flags & MMAL_WRAPPER_FLAG_WAIT))
|
||||
break;
|
||||
vcos_semaphore_wait(&private->sema);
|
||||
}
|
||||
|
||||
return wrapper->status == MMAL_SUCCESS && !*buffer ? MMAL_EAGAIN : wrapper->status;
|
||||
}
|
||||
|
||||
/** Wait for a full buffer to be available on a port */
|
||||
MMAL_STATUS_T mmal_wrapper_buffer_get_full(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T **buffer,
|
||||
uint32_t flags)
|
||||
{
|
||||
MMAL_WRAPPER_PRIVATE_T *private = (MMAL_WRAPPER_PRIVATE_T *)port->userdata;
|
||||
MMAL_WRAPPER_T *wrapper = &private->wrapper;
|
||||
MMAL_QUEUE_T *queue;
|
||||
|
||||
LOG_TRACE("%p, %s", wrapper, port->name);
|
||||
|
||||
if (!buffer || port->type != MMAL_PORT_TYPE_OUTPUT)
|
||||
return MMAL_EINVAL;
|
||||
queue = wrapper->output_queue[port->index];
|
||||
|
||||
while (wrapper->status == MMAL_SUCCESS &&
|
||||
(*buffer = mmal_queue_get(queue)) == NULL)
|
||||
{
|
||||
if (!(flags & MMAL_WRAPPER_FLAG_WAIT))
|
||||
break;
|
||||
vcos_semaphore_wait(&private->sema);
|
||||
}
|
||||
|
||||
return wrapper->status == MMAL_SUCCESS && !*buffer ? MMAL_EAGAIN : wrapper->status;
|
||||
}
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MMAL_WRAPPER_H
|
||||
#define MMAL_WRAPPER_H
|
||||
|
||||
/** \defgroup MmalComponentWrapper utility
|
||||
* \ingroup MmalUtilities
|
||||
* The component wrapper utility functions can be used in place of common sequences
|
||||
* of calls to the MMAL API in order to control a standalone component. It hides some
|
||||
* of the complexity in using standalone components behind a fully synchronous
|
||||
* interface.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Forward type definition for a wrapper */
|
||||
typedef struct MMAL_WRAPPER_T MMAL_WRAPPER_T;
|
||||
|
||||
/** Definition of the callback used by a wrapper to signal back to the client
|
||||
* that a buffer header is available either in the pool or in the output queue.
|
||||
*
|
||||
* @param wrapper Pointer to the wrapper
|
||||
*/
|
||||
typedef void (*MMAL_WRAPPER_CALLBACK_T)(MMAL_WRAPPER_T *wrapper);
|
||||
|
||||
/** Structure describing a wrapper around a component */
|
||||
struct MMAL_WRAPPER_T {
|
||||
|
||||
void *user_data; /**< Field reserved for use by the client. */
|
||||
MMAL_WRAPPER_CALLBACK_T callback; /**< Callback set by the client. */
|
||||
MMAL_COMPONENT_T *component;
|
||||
MMAL_STATUS_T status;
|
||||
|
||||
MMAL_PORT_T *control; /**< Control port (Read Only). */
|
||||
|
||||
uint32_t input_num; /**< Number of input ports (Read Only). */
|
||||
MMAL_PORT_T **input; /**< Array of input ports (Read Only). */
|
||||
MMAL_POOL_T **input_pool; /**< Array of input pools (Read Only). */
|
||||
|
||||
uint32_t output_num; /**< Number of output ports (Read Only). */
|
||||
MMAL_PORT_T **output; /**< Array of output ports (Read Only). */
|
||||
MMAL_POOL_T **output_pool; /**< Array of output pools (Read Only). */
|
||||
MMAL_QUEUE_T **output_queue; /**< Array of output queues (Read Only). */
|
||||
|
||||
/* Used for debug / statistics */
|
||||
int64_t time_setup; /**< Time in microseconds taken to setup the connection. */
|
||||
int64_t time_enable; /**< Time in microseconds taken to enable the connection. */
|
||||
int64_t time_disable; /**< Time in microseconds taken to disable the connection. */
|
||||
|
||||
};
|
||||
|
||||
/** Create a wrapper around a component.
|
||||
* The wrapper shall include a pool of buffer headers for each port. The pools will be suitable
|
||||
* for the current format of its associated port.
|
||||
*
|
||||
* @param wrapper The address of a wrapper pointer that will be set to point to the created
|
||||
* wrapper.
|
||||
* @param name The name of the component to create.
|
||||
* @return MMAL_SUCCESS on success.
|
||||
*/
|
||||
MMAL_STATUS_T mmal_wrapper_create(MMAL_WRAPPER_T **wrapper, const char *name);
|
||||
|
||||
/** \name MMAL wrapper flags
|
||||
* \anchor wrapperflags
|
||||
*/
|
||||
/* @{ */
|
||||
/** The operation should be blocking */
|
||||
#define MMAL_WRAPPER_FLAG_WAIT 1
|
||||
/** The pool for the port should allocate memory for the payloads */
|
||||
#define MMAL_WRAPPER_FLAG_PAYLOAD_ALLOCATE 2
|
||||
/** The port will use shared memory payloads */
|
||||
#define MMAL_WRAPPER_FLAG_PAYLOAD_USE_SHARED_MEMORY 4
|
||||
/* @} */
|
||||
|
||||
/** Enable a port on a component wrapper.
|
||||
*
|
||||
* @param port port to enable
|
||||
* @param flags used to specify payload allocation flags for the pool
|
||||
* @return MMAL_SUCCESS on success.
|
||||
*/
|
||||
MMAL_STATUS_T mmal_wrapper_port_enable(MMAL_PORT_T *port, uint32_t flags);
|
||||
|
||||
/** Disable a port on a component wrapper.
|
||||
*
|
||||
* @param port port to disable
|
||||
* @return MMAL_SUCCESS on success.
|
||||
*/
|
||||
MMAL_STATUS_T mmal_wrapper_port_disable(MMAL_PORT_T *port);
|
||||
|
||||
/** Wait for an empty buffer to be available on a port.
|
||||
*
|
||||
* @param port port to get an empty buffer from
|
||||
* @param buffer points to the retreived buffer on return
|
||||
* @param flags specify MMAL_WRAPPER_FLAG_WAIT for a blocking operation
|
||||
* @return MMAL_SUCCESS on success.
|
||||
*/
|
||||
MMAL_STATUS_T mmal_wrapper_buffer_get_empty(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T **buffer, uint32_t flags);
|
||||
|
||||
/** Wait for a full buffer to be available on a port.
|
||||
*
|
||||
* @param port port to get a full buffer from
|
||||
* @param buffer points to the retreived buffer on return
|
||||
* @param flags specify MMAL_WRAPPER_FLAG_WAIT for a blocking operation
|
||||
* @return MMAL_SUCCESS on success.
|
||||
*/
|
||||
MMAL_STATUS_T mmal_wrapper_buffer_get_full(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T **buffer, uint32_t flags);
|
||||
|
||||
/** Cancel any ongoing blocking operation on a component wrapper.
|
||||
*
|
||||
* @param wrapper The wrapper on which to cancel operations.
|
||||
* @return MMAL_SUCCESS on success.
|
||||
*/
|
||||
MMAL_STATUS_T mmal_wrapper_cancel(MMAL_WRAPPER_T *wrapper);
|
||||
|
||||
/** Destroy a wrapper.
|
||||
* Destroys a component wrapper and any resources it owns.
|
||||
*
|
||||
* @param wrapper The wrapper to be destroyed.
|
||||
* @return MMAL_SUCCESS on success.
|
||||
*/
|
||||
MMAL_STATUS_T mmal_wrapper_destroy(MMAL_WRAPPER_T *wrapper);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* MMAL_WRAPPER_H */
|
||||
@@ -0,0 +1,513 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "mmal.h"
|
||||
#include "util/mmal_util.h"
|
||||
#include "util/mmal_connection.h"
|
||||
#include "mmal_logging.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define CONNECTION_NAME_FORMAT "%s:%.2222s:%i/%s:%.2222s:%i"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MMAL_CONNECTION_T connection; /**< Must be the first member! */
|
||||
MMAL_PORT_T *pool_port; /**< Port used to create the pool */
|
||||
|
||||
/** Reference counting */
|
||||
int refcount;
|
||||
|
||||
} MMAL_CONNECTION_PRIVATE_T;
|
||||
|
||||
/** Callback from an input port. Buffer is released. */
|
||||
static void mmal_connection_bh_in_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
|
||||
{
|
||||
MMAL_PARAM_UNUSED(port);
|
||||
LOG_TRACE("(%s)%p,%p,%p,%i", port->name, port, buffer, buffer->data, (int)buffer->length);
|
||||
|
||||
/* FIXME: Clock ports are bi-directional and a buffer coming from an
|
||||
* "input" clock port can potentially have valid payload data, in
|
||||
* which case it should be queued and not released, however this
|
||||
* callback doesn't have access to the pool queue. */
|
||||
if (port->type == MMAL_PORT_TYPE_CLOCK && buffer->length)
|
||||
{
|
||||
LOG_ERROR("clock ports not supported");
|
||||
}
|
||||
|
||||
/* We're done with the buffer, just recycle it */
|
||||
mmal_buffer_header_release(buffer);
|
||||
}
|
||||
|
||||
/** Callback from an output port. Buffer is queued for the next component. */
|
||||
static void mmal_connection_bh_out_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
|
||||
{
|
||||
MMAL_CONNECTION_T *connection = (MMAL_CONNECTION_T *)port->userdata;
|
||||
MMAL_PARAM_UNUSED(port);
|
||||
LOG_TRACE("(%s)%p,%p,%p,%i", port->name, port, buffer, buffer->data, (int)buffer->length);
|
||||
|
||||
/* Queue the buffer produced by the output port */
|
||||
mmal_queue_put(connection->queue, buffer);
|
||||
|
||||
if (connection->callback)
|
||||
connection->callback(connection);
|
||||
}
|
||||
|
||||
/** Callback from the pool. Buffer is available. */
|
||||
static MMAL_BOOL_T mmal_connection_bh_release_cb(MMAL_POOL_T *pool, MMAL_BUFFER_HEADER_T *buffer,
|
||||
void *userdata)
|
||||
{
|
||||
MMAL_CONNECTION_T *connection = (MMAL_CONNECTION_T *)userdata;
|
||||
MMAL_PARAM_UNUSED(pool);
|
||||
|
||||
/* Queue the buffer produced by the output port */
|
||||
mmal_queue_put(pool->queue, buffer);
|
||||
|
||||
if (connection->callback)
|
||||
connection->callback(connection);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static MMAL_STATUS_T mmal_connection_destroy_internal(MMAL_CONNECTION_T *connection)
|
||||
{
|
||||
MMAL_STATUS_T status;
|
||||
|
||||
if (connection->is_enabled)
|
||||
{
|
||||
status = mmal_connection_disable(connection);
|
||||
if (status != MMAL_SUCCESS)
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Special case for tunnelling */
|
||||
if (connection->flags & MMAL_CONNECTION_FLAG_TUNNELLING)
|
||||
{
|
||||
status = mmal_port_disconnect(connection->out);
|
||||
if (status != MMAL_SUCCESS)
|
||||
LOG_ERROR("connection %s could not be cleared", connection->name);
|
||||
}
|
||||
|
||||
/* Cleanup resources */
|
||||
if (connection->pool)
|
||||
mmal_pool_destroy(connection->pool);
|
||||
if (connection->queue)
|
||||
mmal_queue_destroy(connection->queue);
|
||||
|
||||
vcos_free(connection);
|
||||
return MMAL_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
MMAL_STATUS_T mmal_connection_destroy(MMAL_CONNECTION_T *connection)
|
||||
{
|
||||
MMAL_CONNECTION_PRIVATE_T *private = (MMAL_CONNECTION_PRIVATE_T *)connection;
|
||||
|
||||
LOG_TRACE("%p, %s", connection, connection->name);
|
||||
|
||||
if (--private->refcount)
|
||||
{
|
||||
LOG_DEBUG("delaying destruction of %s (refount %i)", connection->name,
|
||||
private->refcount);
|
||||
return MMAL_SUCCESS;
|
||||
}
|
||||
|
||||
return mmal_connection_destroy_internal(connection);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
MMAL_STATUS_T mmal_connection_create(MMAL_CONNECTION_T **cx,
|
||||
MMAL_PORT_T *out, MMAL_PORT_T *in, uint32_t flags)
|
||||
{
|
||||
MMAL_STATUS_T status = MMAL_ENOMEM;
|
||||
unsigned int name_size = strlen(out->component->name) + strlen(in->component->name) + sizeof(CONNECTION_NAME_FORMAT);
|
||||
unsigned int size = sizeof(MMAL_CONNECTION_PRIVATE_T) + name_size;
|
||||
MMAL_CONNECTION_PRIVATE_T *private;
|
||||
MMAL_CONNECTION_T *connection;
|
||||
char *name;
|
||||
|
||||
/* Sanity checking */
|
||||
if (!cx)
|
||||
return MMAL_EINVAL;
|
||||
|
||||
private = vcos_malloc(size, "mmal connection");
|
||||
if (!private)
|
||||
return MMAL_ENOMEM;
|
||||
memset(private, 0, size);
|
||||
connection = &private->connection;
|
||||
private->refcount = 1;
|
||||
name = (char *)&private[1];
|
||||
|
||||
vcos_snprintf(name, name_size - 1, CONNECTION_NAME_FORMAT,
|
||||
out->component->name,
|
||||
mmal_port_type_to_string(out->type), (int)out->index,
|
||||
in->component->name,
|
||||
mmal_port_type_to_string(in->type), (int)in->index);
|
||||
|
||||
LOG_TRACE("out %p, in %p, flags %x, %s", out, in, flags, name);
|
||||
|
||||
connection->out = out;
|
||||
connection->in = in;
|
||||
connection->flags = flags;
|
||||
connection->name = name;
|
||||
|
||||
connection->time_setup = vcos_getmicrosecs();
|
||||
|
||||
/* Set the format of the input port to match the output one */
|
||||
status = mmal_format_full_copy(in->format, out->format);
|
||||
if (status == MMAL_SUCCESS)
|
||||
status = mmal_port_format_commit(in);
|
||||
if (status != MMAL_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("format not set on input port");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* In pass-through mode we need to propagate the buffer requirements of the
|
||||
* connected input port */
|
||||
if (out->capabilities & MMAL_PORT_CAPABILITY_PASSTHROUGH)
|
||||
{
|
||||
MMAL_PARAMETER_BUFFER_REQUIREMENTS_T param =
|
||||
{{MMAL_PARAMETER_BUFFER_REQUIREMENTS, sizeof(MMAL_PARAMETER_BUFFER_REQUIREMENTS_T)},
|
||||
in->buffer_num_min, in->buffer_size_min, in->buffer_alignment_min,
|
||||
in->buffer_num_recommended, in->buffer_size_recommended};
|
||||
status = mmal_port_parameter_set(out, ¶m.hdr);
|
||||
if (status != MMAL_SUCCESS && status != MMAL_ENOSYS)
|
||||
{
|
||||
LOG_ERROR("failed to propagate buffer requirements");
|
||||
goto error;
|
||||
}
|
||||
status = MMAL_SUCCESS;
|
||||
}
|
||||
|
||||
/* Special case for tunnelling */
|
||||
if (connection->flags & MMAL_CONNECTION_FLAG_TUNNELLING)
|
||||
{
|
||||
status = mmal_port_connect(out, in);
|
||||
if (status != MMAL_SUCCESS)
|
||||
LOG_ERROR("connection could not be made");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Create empty pool of buffer headers for now (will be resized later on) */
|
||||
private->pool_port = (in->capabilities & MMAL_PORT_CAPABILITY_ALLOCATION) ? in : out;
|
||||
if (flags & MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT)
|
||||
private->pool_port = in;
|
||||
if (flags & MMAL_CONNECTION_FLAG_ALLOCATION_ON_OUTPUT)
|
||||
private->pool_port = out;
|
||||
connection->pool = mmal_port_pool_create(private->pool_port, 0, 0);
|
||||
if (!connection->pool)
|
||||
goto error;
|
||||
mmal_pool_callback_set(connection->pool, mmal_connection_bh_release_cb, (void *)connection);
|
||||
|
||||
/* Create a queue to store the buffers from the output port */
|
||||
connection->queue = mmal_queue_create();
|
||||
if (!connection->queue)
|
||||
goto error;
|
||||
|
||||
done:
|
||||
out->userdata = (void *)connection;
|
||||
in->userdata = (void *)connection;
|
||||
connection->time_setup = vcos_getmicrosecs() - connection->time_setup;
|
||||
*cx = connection;
|
||||
return status;
|
||||
|
||||
error:
|
||||
/* coverity[var_deref_model] mmal_connection_destroy_internal will check connection->pool correctly */
|
||||
mmal_connection_destroy_internal(connection);
|
||||
return status == MMAL_SUCCESS ? MMAL_ENOMEM : status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void mmal_connection_acquire(MMAL_CONNECTION_T *connection)
|
||||
{
|
||||
MMAL_CONNECTION_PRIVATE_T *private = (MMAL_CONNECTION_PRIVATE_T *)connection;
|
||||
LOG_TRACE("connection %s(%p), refcount %i", connection->name, connection,
|
||||
private->refcount);
|
||||
private->refcount++;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
MMAL_STATUS_T mmal_connection_release(MMAL_CONNECTION_T *connection)
|
||||
{
|
||||
MMAL_CONNECTION_PRIVATE_T *private = (MMAL_CONNECTION_PRIVATE_T *)connection;
|
||||
LOG_TRACE("connection %s(%p), refcount %i", connection->name, connection,
|
||||
private->refcount);
|
||||
|
||||
if (--private->refcount)
|
||||
return MMAL_SUCCESS;
|
||||
|
||||
LOG_TRACE("destroying connection %s(%p)", connection->name, connection);
|
||||
return mmal_connection_destroy_internal(connection);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
MMAL_STATUS_T mmal_connection_enable(MMAL_CONNECTION_T *connection)
|
||||
{
|
||||
MMAL_PORT_T *in = connection->in, *out = connection->out;
|
||||
uint32_t buffer_num, buffer_size;
|
||||
MMAL_STATUS_T status;
|
||||
|
||||
LOG_TRACE("%p, %s", connection, connection->name);
|
||||
|
||||
if (connection->is_enabled)
|
||||
return MMAL_SUCCESS;
|
||||
|
||||
connection->time_enable = vcos_getmicrosecs();
|
||||
|
||||
/* Override the buffer values with the recommended ones (the port probably knows best) */
|
||||
if (!(connection->flags & MMAL_CONNECTION_FLAG_KEEP_BUFFER_REQUIREMENTS))
|
||||
{
|
||||
if (out->buffer_num_recommended)
|
||||
out->buffer_num = out->buffer_num_recommended;
|
||||
if (out->buffer_size_recommended)
|
||||
out->buffer_size = out->buffer_size_recommended;
|
||||
if (in->buffer_num_recommended)
|
||||
in->buffer_num = in->buffer_num_recommended;
|
||||
if (in->buffer_size_recommended)
|
||||
in->buffer_size = in->buffer_size_recommended;
|
||||
}
|
||||
|
||||
/* Special case for tunnelling */
|
||||
if (connection->flags & MMAL_CONNECTION_FLAG_TUNNELLING)
|
||||
{
|
||||
/* Enable port. No callback because the port is connected. Other end of the connection
|
||||
* will be enabled automatically. */
|
||||
status = mmal_port_enable(out, NULL);
|
||||
if (status)
|
||||
LOG_ERROR("output port couldn't be enabled");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Set the buffering properties on both ports */
|
||||
buffer_num = MMAL_MAX(out->buffer_num, in->buffer_num);
|
||||
buffer_size = MMAL_MAX(out->buffer_size, in->buffer_size);
|
||||
out->buffer_num = in->buffer_num = buffer_num;
|
||||
out->buffer_size = in->buffer_size = buffer_size;
|
||||
|
||||
/* In pass-through mode there isn't any need to allocate memory */
|
||||
if (out->capabilities & MMAL_PORT_CAPABILITY_PASSTHROUGH)
|
||||
buffer_size = 0;
|
||||
|
||||
/* Resize the output pool */
|
||||
status = mmal_pool_resize(connection->pool, buffer_num, buffer_size);
|
||||
if (status != MMAL_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("couldn't resize pool");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Enable output port. The callback specified here is the function which
|
||||
* will be called when an empty buffer header comes back to the port. */
|
||||
status = mmal_port_enable(out, mmal_connection_bh_out_cb);
|
||||
if(status)
|
||||
{
|
||||
LOG_ERROR("output port couldn't be enabled");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Enable input port. The callback specified here is the function which
|
||||
* will be called when an empty buffer header comes back to the port. */
|
||||
status = mmal_port_enable(in, mmal_connection_bh_in_cb);
|
||||
if(status)
|
||||
{
|
||||
LOG_ERROR("input port couldn't be enabled");
|
||||
mmal_port_disable(out);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Clock ports need buffers to send clock updates, so
|
||||
* populate both connected clock ports */
|
||||
if ((out->type == MMAL_PORT_TYPE_CLOCK) && (in->type == MMAL_PORT_TYPE_CLOCK))
|
||||
{
|
||||
MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(connection->pool->queue);
|
||||
while (buffer)
|
||||
{
|
||||
mmal_port_send_buffer(out, buffer);
|
||||
buffer = mmal_queue_get(connection->pool->queue);
|
||||
if (buffer)
|
||||
{
|
||||
mmal_port_send_buffer(in, buffer);
|
||||
buffer = mmal_queue_get(connection->pool->queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
connection->time_enable = vcos_getmicrosecs() - connection->time_enable;
|
||||
connection->is_enabled = status == MMAL_SUCCESS;
|
||||
return status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
MMAL_STATUS_T mmal_connection_disable(MMAL_CONNECTION_T *connection)
|
||||
{
|
||||
MMAL_STATUS_T status;
|
||||
MMAL_BUFFER_HEADER_T *buffer;
|
||||
|
||||
LOG_TRACE("%p, %s", connection, connection->name);
|
||||
|
||||
if (!connection->is_enabled)
|
||||
return MMAL_SUCCESS;
|
||||
|
||||
connection->time_disable = vcos_getmicrosecs();
|
||||
|
||||
/* Special case for tunnelling */
|
||||
if (connection->flags & MMAL_CONNECTION_FLAG_TUNNELLING)
|
||||
{
|
||||
/* Disable port. Other end of the connection will be disabled automatically. */
|
||||
status = mmal_port_disable(connection->out);
|
||||
if (status)
|
||||
LOG_ERROR("output port couldn't be disabled");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Disable input port. */
|
||||
status = mmal_port_disable(connection->in);
|
||||
if(status)
|
||||
{
|
||||
LOG_ERROR("input port couldn't be disabled");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Disable output port */
|
||||
status = mmal_port_disable(connection->out);
|
||||
if(status)
|
||||
{
|
||||
LOG_ERROR("output port couldn't be disabled");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Flush the queue */
|
||||
buffer = mmal_queue_get(connection->queue);
|
||||
while (buffer)
|
||||
{
|
||||
mmal_buffer_header_release(buffer);
|
||||
buffer = mmal_queue_get(connection->queue);
|
||||
}
|
||||
vcos_assert(mmal_queue_length(connection->pool->queue) == connection->pool->headers_num);
|
||||
|
||||
done:
|
||||
connection->time_disable = vcos_getmicrosecs() - connection->time_disable;
|
||||
connection->is_enabled = !(status == MMAL_SUCCESS);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static MMAL_STATUS_T mmal_connection_reconfigure(MMAL_CONNECTION_T *connection, MMAL_ES_FORMAT_T *format)
|
||||
{
|
||||
MMAL_STATUS_T status;
|
||||
LOG_TRACE("%p, %s", connection, connection->name);
|
||||
|
||||
status = mmal_connection_disable(connection);
|
||||
if (status != MMAL_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("connection couldn't be disabled");
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Set the new format for the output port */
|
||||
status = mmal_format_full_copy(connection->out->format, format);
|
||||
if (status == MMAL_SUCCESS)
|
||||
status = mmal_port_format_commit(connection->out);
|
||||
if (status != MMAL_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("commit failed on port %s(%p) (%i)",
|
||||
connection->out->name, connection->out, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Set the new format for the input port */
|
||||
status = mmal_format_full_copy(connection->in->format, connection->out->format);
|
||||
if (status == MMAL_SUCCESS)
|
||||
status = mmal_port_format_commit(connection->in);
|
||||
if (status != MMAL_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("commit failed on port %s(%p) (%i)",
|
||||
connection->in->name, connection->in, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Enable ports */
|
||||
status = mmal_connection_enable(connection);
|
||||
if (status)
|
||||
{
|
||||
LOG_ERROR("connection couldn't be enabled");
|
||||
return status;
|
||||
}
|
||||
|
||||
return MMAL_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
MMAL_STATUS_T mmal_connection_event_format_changed(MMAL_CONNECTION_T *connection,
|
||||
MMAL_BUFFER_HEADER_T *buffer)
|
||||
{
|
||||
MMAL_EVENT_FORMAT_CHANGED_T *event;
|
||||
MMAL_STATUS_T status;
|
||||
|
||||
LOG_TRACE("%p, %s", connection, connection->name);
|
||||
|
||||
if (buffer->cmd != MMAL_EVENT_FORMAT_CHANGED)
|
||||
return MMAL_EINVAL;
|
||||
|
||||
event = mmal_event_format_changed_get(buffer);
|
||||
if (!event)
|
||||
return MMAL_EINVAL;
|
||||
|
||||
/* If we don't need to recreate our buffers then we can just forward the event
|
||||
* to the next component (so it gets configured properly) */
|
||||
if ((connection->in->capabilities & MMAL_PORT_CAPABILITY_SUPPORTS_EVENT_FORMAT_CHANGE) &&
|
||||
event->buffer_size_min <= connection->out->buffer_size &&
|
||||
event->buffer_num_min <= connection->out->buffer_num)
|
||||
{
|
||||
status = mmal_format_full_copy(connection->out->format, event->format);
|
||||
if (status == MMAL_SUCCESS)
|
||||
status = mmal_port_format_commit(connection->out);
|
||||
if (status != MMAL_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("format commit failed on port %s(%p) (%i)",
|
||||
connection->out->name, connection->out, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
mmal_buffer_header_acquire(buffer);
|
||||
status = mmal_port_send_buffer(connection->in, buffer);
|
||||
if (status != MMAL_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("buffer send failed on port %s(%p) (%i)",
|
||||
connection->in->name, connection->in, status);
|
||||
mmal_buffer_header_release(buffer);
|
||||
return status;
|
||||
}
|
||||
|
||||
return MMAL_SUCCESS;
|
||||
}
|
||||
|
||||
/* Otherwise we have to reconfigure our pipeline */
|
||||
return mmal_connection_reconfigure(connection, event->format);
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MMAL_CONNECTION_H
|
||||
#define MMAL_CONNECTION_H
|
||||
|
||||
/** \defgroup MmalConnectionUtility Port connection utility
|
||||
* \ingroup MmalUtilities
|
||||
* The port connection utility functions can be used in place of common sequences
|
||||
* of calls to the MMAL API in order to process buffers being passed between two
|
||||
* ports.
|
||||
*
|
||||
* \section ProcessingConnectionBufferHeaders Processing connection buffer headers
|
||||
* Either in response to the client callback function being called, or simply on a
|
||||
* timer, the client will need to process the buffer headers of the connection
|
||||
* (unless tunneling is used).
|
||||
*
|
||||
* Buffer headers that are in the pool queue will need to be sent to the output port,
|
||||
* while buffer headers in the connection queue are sent to the input port. The
|
||||
* buffer headers in the connection queue may contain pixel data (the cmd field is
|
||||
* zero) or an event (the cmd field is non-zero). In general, pixel data buffer
|
||||
* headers need to be passed on, while event buffer headers are released. In the
|
||||
* case of the format changed event, mmal_connection_event_format_changed() can be
|
||||
* called before the event is released.
|
||||
*
|
||||
* Other, specialized use cases may also be implemented, such as getting and
|
||||
* immediately releasing buffer headers from the connection queue in order to
|
||||
* prevent their propagation. This could be used to drop out video, for example.
|
||||
*
|
||||
* \section TunnellingConnections Tunnelling connections
|
||||
* If the \ref MMAL_CONNECTION_FLAG_TUNNELLING flag is set when the connection is
|
||||
* created, MMAL tunneling will be used. This automates the passing of the buffer
|
||||
* headers between the output port and input port, and back again. It will also do
|
||||
* this as efficiently as possible, avoiding trips between the ARM and the VideoCore
|
||||
* if both components are implemented on the VideoCore. The consequence of this is
|
||||
* that there is no client callback made as buffer headers get transferred.
|
||||
*
|
||||
* The client can still monitor the control port of a component (usually a sink
|
||||
* component, such as video_render) for the end of stream, in order to know when to
|
||||
* dismantle the connection.
|
||||
*
|
||||
* \section ConnectionClientCallback Client callback
|
||||
* When not using tunnelling, the client callback function is called each time a
|
||||
* buffer arrives from a port (either input or output).
|
||||
*
|
||||
* \note The callback is made on a different thread from the one used by the
|
||||
* client to set up the connection, so care must be taken with thread safety.
|
||||
* One option is to raise a signal to the main client thread that queue processing
|
||||
* needs to be done, another is for the callback to perform the queue processing
|
||||
* itself.
|
||||
*
|
||||
* The client can also store an opaque pointer in the connection object, which is
|
||||
* never used by the MMAL code and is only meaningful to the client.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \name Connection flags
|
||||
* \anchor connectionflags
|
||||
* The following flags describe the properties of the connection. */
|
||||
/* @{ */
|
||||
/** The connection is tunnelled. Buffer headers do not transit via the client but
|
||||
* directly from the output port to the input port. */
|
||||
#define MMAL_CONNECTION_FLAG_TUNNELLING 0x1
|
||||
/** Force the pool of buffer headers used by the connection to be allocated on the input port. */
|
||||
#define MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT 0x2
|
||||
/** Force the pool of buffer headers used by the connection to be allocated on the output port. */
|
||||
#define MMAL_CONNECTION_FLAG_ALLOCATION_ON_OUTPUT 0x4
|
||||
/** Specify that the connection should not modify the buffer requirements. */
|
||||
#define MMAL_CONNECTION_FLAG_KEEP_BUFFER_REQUIREMENTS 0x8
|
||||
/** The connection is flagged as direct. This doesn't change the behaviour of
|
||||
* the connection itself but is used by the the graph utility to specify that
|
||||
* the buffer should be sent to the input port from with the port callback. */
|
||||
#define MMAL_CONNECTION_FLAG_DIRECT 0x10
|
||||
/* @} */
|
||||
|
||||
/** Forward type definition for a connection */
|
||||
typedef struct MMAL_CONNECTION_T MMAL_CONNECTION_T;
|
||||
|
||||
/** Definition of the callback used by a connection to signal back to the client
|
||||
* that a buffer header is available either in the pool or in the output queue.
|
||||
*
|
||||
* @param connection Pointer to the connection
|
||||
*/
|
||||
typedef void (*MMAL_CONNECTION_CALLBACK_T)(MMAL_CONNECTION_T *connection);
|
||||
|
||||
/** Structure describing a connection between 2 ports (1 output and 1 input port) */
|
||||
struct MMAL_CONNECTION_T {
|
||||
|
||||
void *user_data; /**< Field reserved for use by the client. */
|
||||
MMAL_CONNECTION_CALLBACK_T callback; /**< Callback set by the client. */
|
||||
|
||||
uint32_t is_enabled; /**< Specifies whether the connection is enabled or not (Read Only). */
|
||||
|
||||
uint32_t flags; /**< Flags passed during the create call (Read Only). A bitwise
|
||||
* combination of \ref connectionflags "Connection flags" values.
|
||||
*/
|
||||
MMAL_PORT_T *in; /**< Input port used for the connection (Read Only). */
|
||||
MMAL_PORT_T *out; /**< Output port used for the connection (Read Only). */
|
||||
|
||||
MMAL_POOL_T *pool; /**< Pool of buffer headers used by the output port (Read Only). */
|
||||
MMAL_QUEUE_T *queue; /**< Queue for the buffer headers produced by the output port (Read Only). */
|
||||
|
||||
const char *name; /**< Connection name (Read Only). Used for debugging purposes. */
|
||||
|
||||
/* Used for debug / statistics */
|
||||
int64_t time_setup; /**< Time in microseconds taken to setup the connection. */
|
||||
int64_t time_enable; /**< Time in microseconds taken to enable the connection. */
|
||||
int64_t time_disable; /**< Time in microseconds taken to disable the connection. */
|
||||
};
|
||||
|
||||
/** Create a connection between two ports.
|
||||
* The connection shall include a pool of buffer headers suitable for the current format of
|
||||
* the output port. The format of the input port shall have been set to the same as that of
|
||||
* the input port.
|
||||
* Note that connections are reference counted and creating a connection automatically
|
||||
* acquires a reference to it (released when \ref mmal_connection_destroy is called).
|
||||
*
|
||||
* @param connection The address of a connection pointer that will be set to point to the created
|
||||
* connection.
|
||||
* @param out The output port to use for the connection.
|
||||
* @param in The input port to use for the connection.
|
||||
* @param flags The flags specifying which type of connection should be created.
|
||||
* A bitwise combination of \ref connectionflags "Connection flags" values.
|
||||
* @return MMAL_SUCCESS on success.
|
||||
*/
|
||||
MMAL_STATUS_T mmal_connection_create(MMAL_CONNECTION_T **connection,
|
||||
MMAL_PORT_T *out, MMAL_PORT_T *in, uint32_t flags);
|
||||
|
||||
/** Acquire a reference on a connection.
|
||||
* Acquiring a reference on a connection will prevent a connection from being destroyed until
|
||||
* the acquired reference is released (by a call to \ref mmal_connection_destroy).
|
||||
* References are internally counted so all acquired references need a matching call to
|
||||
* release them.
|
||||
*
|
||||
* @param connection connection to acquire
|
||||
*/
|
||||
void mmal_connection_acquire(MMAL_CONNECTION_T *connection);
|
||||
|
||||
/** Release a reference on a connection
|
||||
* Release an acquired reference on a connection. Triggers the destruction of the connection when
|
||||
* the last reference is being released.
|
||||
* \note This is in fact an alias of \ref mmal_connection_destroy which is added to make client
|
||||
* code clearer.
|
||||
*
|
||||
* @param connection connection to release
|
||||
* @return MMAL_SUCCESS on success
|
||||
*/
|
||||
MMAL_STATUS_T mmal_connection_release(MMAL_CONNECTION_T *connection);
|
||||
|
||||
/** Destroy a connection.
|
||||
* Release an acquired reference on a connection. Only actually destroys the connection when
|
||||
* the last reference is being released.
|
||||
* The actual destruction of the connection will start by disabling it, if necessary.
|
||||
* Any pool, queue, and so on owned by the connection shall then be destroyed.
|
||||
*
|
||||
* @param connection The connection to be destroyed.
|
||||
* @return MMAL_SUCCESS on success.
|
||||
*/
|
||||
MMAL_STATUS_T mmal_connection_destroy(MMAL_CONNECTION_T *connection);
|
||||
|
||||
/** Enable a connection.
|
||||
* The format of the two ports must have been committed before calling this function,
|
||||
* although note that on creation, the connection automatically copies and commits the
|
||||
* output port's format to the input port.
|
||||
*
|
||||
* The MMAL_CONNECTION_T::callback field must have been set if the \ref MMAL_CONNECTION_FLAG_TUNNELLING
|
||||
* flag was not specified on creation. The client may also set the MMAL_CONNECTION_T::user_data
|
||||
* in order to get a pointer passed, via the connection, to the callback.
|
||||
*
|
||||
* @param connection The connection to be enabled.
|
||||
* @return MMAL_SUCCESS on success.
|
||||
*/
|
||||
MMAL_STATUS_T mmal_connection_enable(MMAL_CONNECTION_T *connection);
|
||||
|
||||
/** Disable a connection.
|
||||
*
|
||||
* @param connection The connection to be disabled.
|
||||
* @return MMAL_SUCCESS on success.
|
||||
*/
|
||||
MMAL_STATUS_T mmal_connection_disable(MMAL_CONNECTION_T *connection);
|
||||
|
||||
/** Apply a format changed event to the connection.
|
||||
* This function can be used when the client is processing buffer headers and receives
|
||||
* a format changed event (\ref MMAL_EVENT_FORMAT_CHANGED). The connection is
|
||||
* reconfigured, changing the format of the ports, the number of buffer headers and
|
||||
* the size of the payload buffers as necessary.
|
||||
*
|
||||
* @param connection The connection to which the event shall be applied.
|
||||
* @param buffer The buffer containing a format changed event.
|
||||
* @return MMAL_SUCCESS on success.
|
||||
*/
|
||||
MMAL_STATUS_T mmal_connection_event_format_changed(MMAL_CONNECTION_T *connection,
|
||||
MMAL_BUFFER_HEADER_T *buffer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* MMAL_CONNECTION_H */
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MMAL_DEFAULT_COMPONENTS_H
|
||||
#define MMAL_DEFAULT_COMPONENTS_H
|
||||
|
||||
/** \defgroup MmalDefaultComponents List of default components
|
||||
* This provides a list of default components on a per platform basis.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define MMAL_COMPONENT_DEFAULT_CONTAINER_READER "container_reader"
|
||||
#define MMAL_COMPONENT_DEFAULT_CONTAINER_WRITER "container_writer"
|
||||
|
||||
#if defined(ENABLE_MMAL_STANDALONE)
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_DECODER "avcodec.video_decode"
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_ENCODER "avcodec.video_encode"
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER "sdl.video_render"
|
||||
# define MMAL_COMPONENT_DEFAULT_IMAGE_DECODER "avcodec.video_decode"
|
||||
# define MMAL_COMPONENT_DEFAULT_IMAGE_ENCODER "avcodec.video_encode"
|
||||
# define MMAL_COMPONENT_DEFAULT_CAMERA "artificial_camera"
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_CONVERTER "avcodec.video_convert"
|
||||
# define MMAL_COMPONENT_DEFAULT_SPLITTER "splitter"
|
||||
# define MMAL_COMPONENT_DEFAULT_SCHEDULER "scheduler"
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_INJECTER "video_inject"
|
||||
# define MMAL_COMPONENT_DEFAULT_AUDIO_DECODER "avcodec.audio_decode"
|
||||
# define MMAL_COMPONENT_DEFAULT_AUDIO_RENDERER "sdl.audio_render"
|
||||
# define MMAL_COMPONENT_DEFAULT_MIRACAST "miracast"
|
||||
# define MMAL_COMPONENT_DEFAULT_CLOCK "clock"
|
||||
#elif defined(__VIDEOCORE__)
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_DECODER "ril.video_decode"
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_ENCODER "ril.video_encode"
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER "ril.video_render"
|
||||
# define MMAL_COMPONENT_DEFAULT_IMAGE_DECODER "ril.image_decode"
|
||||
# define MMAL_COMPONENT_DEFAULT_IMAGE_ENCODER "ril.image_encode"
|
||||
# define MMAL_COMPONENT_DEFAULT_CAMERA "ril.camera"
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_CONVERTER "video_convert"
|
||||
# define MMAL_COMPONENT_DEFAULT_SPLITTER "splitter"
|
||||
# define MMAL_COMPONENT_DEFAULT_SCHEDULER "scheduler"
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_INJECTER "video_inject"
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_SPLITTER "ril.video_splitter"
|
||||
# define MMAL_COMPONENT_DEFAULT_AUDIO_DECODER "none"
|
||||
# define MMAL_COMPONENT_DEFAULT_AUDIO_RENDERER "ril.audio_render"
|
||||
# define MMAL_COMPONENT_DEFAULT_MIRACAST "miracast"
|
||||
# define MMAL_COMPONENT_DEFAULT_CLOCK "clock"
|
||||
#else
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_DECODER "vc.ril.video_decode"
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_ENCODER "vc.ril.video_encode"
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER "vc.ril.video_render"
|
||||
# define MMAL_COMPONENT_DEFAULT_IMAGE_DECODER "vc.ril.image_decode"
|
||||
# define MMAL_COMPONENT_DEFAULT_IMAGE_ENCODER "vc.ril.image_encode"
|
||||
# define MMAL_COMPONENT_DEFAULT_CAMERA "vc.ril.camera"
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_CONVERTER "vc.video_convert"
|
||||
# define MMAL_COMPONENT_DEFAULT_SPLITTER "vc.splitter"
|
||||
# define MMAL_COMPONENT_DEFAULT_SCHEDULER "vc.scheduler"
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_INJECTER "vc.video_inject"
|
||||
# define MMAL_COMPONENT_DEFAULT_VIDEO_SPLITTER "vc.ril.video_splitter"
|
||||
# define MMAL_COMPONENT_DEFAULT_AUDIO_DECODER "none"
|
||||
# define MMAL_COMPONENT_DEFAULT_AUDIO_RENDERER "vc.ril.audio_render"
|
||||
# define MMAL_COMPONENT_DEFAULT_MIRACAST "vc.miracast"
|
||||
# define MMAL_COMPONENT_DEFAULT_CLOCK "vc.clock"
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* MMAL_DEFAULT_COMPONENTS_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MMAL_GRAPH_H
|
||||
#define MMAL_GRAPH_H
|
||||
|
||||
#include "util/mmal_connection.h"
|
||||
|
||||
/** \defgroup MmalGraphUtility Graph Utility
|
||||
* \ingroup MmalUtilities
|
||||
* The graph utility functions allows one to easily create graphs of MMAL components.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** List of topology types */
|
||||
typedef enum
|
||||
{
|
||||
MMAL_GRAPH_TOPOLOGY_ALL = 0, /**< All input ports and output ports are linked */
|
||||
MMAL_GRAPH_TOPOLOGY_STRAIGHT, /**< Input ports and output ports of the same index are linked */
|
||||
MMAL_GRAPH_TOPOLOGY_CUSTOM, /**< Custom defined topology */
|
||||
MMAL_GRAPH_TOPOLOGY_MAX
|
||||
|
||||
} MMAL_GRAPH_TOPOLOGY_T;
|
||||
|
||||
/** Structure describing a graph */
|
||||
typedef struct MMAL_GRAPH_T
|
||||
{
|
||||
/** Pointer to private data of the client */
|
||||
struct MMAL_GRAPH_USERDATA_T *userdata;
|
||||
|
||||
/** Optional callback that the client can set to get notified when the graph is going to be destroyed */
|
||||
void (*pf_destroy)(struct MMAL_GRAPH_T *);
|
||||
|
||||
/** Optional callback that the client can set to intercept parameter requests on ports exposed by the graph */
|
||||
MMAL_STATUS_T (*pf_parameter_set)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port, const MMAL_PARAMETER_HEADER_T *param);
|
||||
/** Optional callback that the client can set to intercept parameter requests on ports exposed by the graph */
|
||||
MMAL_STATUS_T (*pf_parameter_get)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port, MMAL_PARAMETER_HEADER_T *param);
|
||||
/** Optional callback that the client can set to intercept format commit calls on ports exposed by the graph */
|
||||
MMAL_STATUS_T (*pf_format_commit)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port);
|
||||
/** Optional callback that the client can set to intercept send buffer calls on ports exposed by the graph */
|
||||
MMAL_STATUS_T (*pf_send_buffer)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer);
|
||||
/** Optional callback that the client can set to intercept buffer callbacks on ports exposed by the graph */
|
||||
MMAL_STATUS_T (*pf_return_buffer)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer);
|
||||
/** Optional callback that the client can set to intercept payload alloc calls on ports exposed by the graph */
|
||||
MMAL_STATUS_T (*pf_payload_alloc)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port, uint32_t payload_size, uint8_t **);
|
||||
/** Optional callback that the client can set to intercept payload free calls on ports exposed by the graph */
|
||||
MMAL_STATUS_T (*pf_payload_free)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port, uint8_t *payload);
|
||||
/** Optional callback that the client can set to intercept flush calls on ports exposed by the graph */
|
||||
MMAL_STATUS_T (*pf_flush)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port);
|
||||
/** Optional callback that the client can set to control callbacks from the internal components of the graph */
|
||||
/** Optional callback that the client can set to intercept enable calls on ports exposed by the graph */
|
||||
MMAL_STATUS_T (*pf_enable)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port);
|
||||
/** Optional callback that the client can set to intercept disable calls on ports exposed by the graph */
|
||||
MMAL_STATUS_T (*pf_disable)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port);
|
||||
/** Optional callback that the client can set to control callbacks from the internal components of the graph */
|
||||
MMAL_STATUS_T (*pf_control_callback)(struct MMAL_GRAPH_T *, MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer);
|
||||
/** Optional callback that the client can set to intercept component_enable/disable calls made to the graph */
|
||||
MMAL_STATUS_T (*pf_graph_enable)(struct MMAL_GRAPH_T *, MMAL_BOOL_T enable);
|
||||
/** Optional callback that the client can set to intercept buffers going through internal connections.
|
||||
* This will only be triggered if the connection is not tunnelled */
|
||||
MMAL_STATUS_T (*pf_connection_buffer)(struct MMAL_GRAPH_T *, MMAL_CONNECTION_T *connection, MMAL_BUFFER_HEADER_T *buffer);
|
||||
|
||||
} MMAL_GRAPH_T;
|
||||
|
||||
/** Create an instance of a graph.
|
||||
* The newly created graph will need to be populated by the client.
|
||||
*
|
||||
* @param graph returned graph
|
||||
* @param userdata_size size to be allocated for the userdata field
|
||||
* @return MMAL_SUCCESS on success
|
||||
*/
|
||||
MMAL_STATUS_T mmal_graph_create(MMAL_GRAPH_T **graph, unsigned int userdata_size);
|
||||
|
||||
/** Add a component to a graph.
|
||||
* Allows the client to add a component to the graph.
|
||||
*
|
||||
* @param graph instance of the graph
|
||||
* @param component component to add to a graph
|
||||
* @return MMAL_SUCCESS on success
|
||||
*/
|
||||
MMAL_STATUS_T mmal_graph_add_component(MMAL_GRAPH_T *graph, MMAL_COMPONENT_T *component);
|
||||
|
||||
/** Describe the topology of the ports of a component.
|
||||
* Allows the client to describe the topology of a component. This information
|
||||
* is used by the graph to choose which action to perform when
|
||||
* enabling / disabling / committing / flushing a port exposed by the graph.
|
||||
* Note that by default the topology of a component is set to MMAL_GRAPH_TOPOLOGY_ALL.
|
||||
*
|
||||
* @param graph instance of the graph
|
||||
* @param component component to describe
|
||||
* @param topology type of topology used by this component
|
||||
* @param input output index (or -1 if sink) linked to each input port
|
||||
* @param input_num number of indexes in the input list
|
||||
* @param output input index (or -1 if source) linked to each output port
|
||||
* @param output_num number of indexes in the output list
|
||||
* @return MMAL_SUCCESS on success
|
||||
*/
|
||||
MMAL_STATUS_T mmal_graph_component_topology(MMAL_GRAPH_T *graph, MMAL_COMPONENT_T *component,
|
||||
MMAL_GRAPH_TOPOLOGY_T topology, int8_t *input, unsigned int input_num,
|
||||
int8_t *output, unsigned int output_num);
|
||||
|
||||
/** Add a port to a graph.
|
||||
* Allows the client to add an input or output port to a graph. The given port
|
||||
* will effectively become an end point for the graph.
|
||||
*
|
||||
* @param graph instance of the graph
|
||||
* @param port port to add to the graph
|
||||
* @return MMAL_SUCCESS on success
|
||||
*/
|
||||
MMAL_STATUS_T mmal_graph_add_port(MMAL_GRAPH_T *graph, MMAL_PORT_T *port);
|
||||
|
||||
/** Add a connection to a graph.
|
||||
* Allows the client to add an internal connection to a graph.
|
||||
*
|
||||
* @param graph instance of the graph
|
||||
* @param connection connection to add to the graph
|
||||
* @return MMAL_SUCCESS on success
|
||||
*/
|
||||
MMAL_STATUS_T mmal_graph_add_connection(MMAL_GRAPH_T *graph, MMAL_CONNECTION_T *connection);
|
||||
|
||||
/** Create a new component and add it to a graph.
|
||||
* Allows the client to create and add a component to the graph.
|
||||
*
|
||||
* @param graph instance of the graph
|
||||
* @param name name of the component to create
|
||||
* @param component if not NULL, will contain a pointer to the created component
|
||||
* @return MMAL_SUCCESS on success
|
||||
*/
|
||||
MMAL_STATUS_T mmal_graph_new_component(MMAL_GRAPH_T *graph, const char *name,
|
||||
MMAL_COMPONENT_T **component);
|
||||
|
||||
/** Create and add a connection to a graph.
|
||||
* Allows the client to create and add an internal connection to a graph.
|
||||
*
|
||||
* @param graph instance of the graph
|
||||
* @param out the output port to use for the connection
|
||||
* @param in the input port to use for the connection
|
||||
* @param flags the flags specifying which type of connection should be created
|
||||
* @param connection if not NULL, will contain a pointer to the created connection
|
||||
* @return MMAL_SUCCESS on success
|
||||
*/
|
||||
MMAL_STATUS_T mmal_graph_new_connection(MMAL_GRAPH_T *graph, MMAL_PORT_T *out, MMAL_PORT_T *in,
|
||||
uint32_t flags, MMAL_CONNECTION_T **connection);
|
||||
|
||||
/** Definition of the callback used by a graph to send events to the client.
|
||||
*
|
||||
* @param graph the graph sending the event
|
||||
* @param port the port which generated the event
|
||||
* @param buffer the buffer header containing the event data
|
||||
* @param cb_data data passed back to the client when the callback is invoked
|
||||
*/
|
||||
typedef void (*MMAL_GRAPH_EVENT_CB)(MMAL_GRAPH_T *graph, MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer,
|
||||
void *cb_data);
|
||||
|
||||
/** Enable the graph and start processing.
|
||||
*
|
||||
* @param graph the graph to enable
|
||||
* @param cb the callback to invoke when an event occurs on any of the internal control ports
|
||||
* @param cb_data data passed back to the client when the callback is invoked
|
||||
*
|
||||
* @return MMAL_SUCCESS on success
|
||||
*/
|
||||
MMAL_STATUS_T mmal_graph_enable(MMAL_GRAPH_T *graph, MMAL_GRAPH_EVENT_CB cb, void *cb_data);
|
||||
|
||||
MMAL_STATUS_T mmal_graph_disable(MMAL_GRAPH_T *graph);
|
||||
|
||||
/** Find a port in the graph.
|
||||
*
|
||||
* @param graph graph instance
|
||||
* @param name name of the component of interest
|
||||
* @param type type of port (in/out)
|
||||
* @param index which port index within the component
|
||||
*
|
||||
* @return port, or NULL if not found
|
||||
*/
|
||||
MMAL_PORT_T *mmal_graph_find_port(MMAL_GRAPH_T *graph,
|
||||
const char *name,
|
||||
MMAL_PORT_TYPE_T type,
|
||||
unsigned index);
|
||||
|
||||
/** Create an instance of a component from a graph.
|
||||
* The newly created component will expose input and output ports to the client.
|
||||
* Not that all the exposed ports will be in a disabled state by default.
|
||||
*
|
||||
* @param graph graph to create the component from
|
||||
* @param name name of the component to create
|
||||
* @param component returned component
|
||||
* @return MMAL_SUCCESS on success
|
||||
*/
|
||||
MMAL_STATUS_T mmal_graph_build(MMAL_GRAPH_T *ctx,
|
||||
const char *name, MMAL_COMPONENT_T **component);
|
||||
|
||||
/** Component constructor for a graph.
|
||||
* FIXME: private function
|
||||
*
|
||||
* @param name name of the component to create
|
||||
* @param component component
|
||||
* @return MMAL_SUCCESS on success
|
||||
*/
|
||||
MMAL_STATUS_T mmal_graph_component_constructor(const char *name, MMAL_COMPONENT_T *component);
|
||||
|
||||
/** Destroy a previously created graph
|
||||
* @param graph graph to destroy
|
||||
* @return MMAL_SUCCESS on success
|
||||
*/
|
||||
MMAL_STATUS_T mmal_graph_destroy(MMAL_GRAPH_T *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* MMAL_GRAPH_H */
|
||||
@@ -0,0 +1,915 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "mmal.h"
|
||||
#include "util/mmal_il.h"
|
||||
#include "interface/vmcs_host/khronos/IL/OMX_Broadcom.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
static struct {
|
||||
MMAL_STATUS_T mmal;
|
||||
OMX_ERRORTYPE omx;
|
||||
} mmal_omx_error[] =
|
||||
{
|
||||
{MMAL_SUCCESS, OMX_ErrorNone},
|
||||
{MMAL_ENOMEM, OMX_ErrorInsufficientResources},
|
||||
{MMAL_ENOSPC, OMX_ErrorInsufficientResources},
|
||||
{MMAL_EINVAL, OMX_ErrorBadParameter},
|
||||
{MMAL_ENOSYS, OMX_ErrorNotImplemented},
|
||||
{(MMAL_STATUS_T)-1, OMX_ErrorUndefined},
|
||||
};
|
||||
|
||||
OMX_ERRORTYPE mmalil_error_to_omx(MMAL_STATUS_T status)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_error[i].mmal != (MMAL_STATUS_T)-1; i++)
|
||||
if(mmal_omx_error[i].mmal == status) break;
|
||||
return mmal_omx_error[i].omx;
|
||||
}
|
||||
|
||||
MMAL_STATUS_T mmalil_error_to_mmal(OMX_ERRORTYPE error)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_error[i].mmal != (MMAL_STATUS_T)-1; i++)
|
||||
if(mmal_omx_error[i].omx == error) break;
|
||||
return mmal_omx_error[i].mmal;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
OMX_U32 mmalil_buffer_flags_to_omx(uint32_t flags)
|
||||
{
|
||||
OMX_U32 omx_flags = 0;
|
||||
|
||||
if(flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME)
|
||||
omx_flags |= OMX_BUFFERFLAG_SYNCFRAME;
|
||||
if(flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
|
||||
omx_flags |= OMX_BUFFERFLAG_ENDOFFRAME;
|
||||
if(flags & MMAL_BUFFER_HEADER_FLAG_EOS)
|
||||
omx_flags |= OMX_BUFFERFLAG_EOS;
|
||||
if(flags & MMAL_BUFFER_HEADER_FLAG_CONFIG)
|
||||
omx_flags |= OMX_BUFFERFLAG_CODECCONFIG;
|
||||
if(flags & MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY)
|
||||
omx_flags |= OMX_BUFFERFLAG_DISCONTINUITY;
|
||||
if (flags & MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO)
|
||||
omx_flags |= OMX_BUFFERFLAG_CODECSIDEINFO;
|
||||
if (flags & MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT)
|
||||
omx_flags |= OMX_BUFFERFLAG_CAPTURE_PREVIEW;
|
||||
if (flags & MMAL_BUFFER_HEADER_FLAG_CORRUPTED)
|
||||
omx_flags |= OMX_BUFFERFLAG_DATACORRUPT;
|
||||
if (flags & MMAL_BUFFER_HEADER_FLAG_DECODEONLY)
|
||||
omx_flags |= OMX_BUFFERFLAG_DECODEONLY;
|
||||
if (flags & MMAL_BUFFER_HEADER_FLAG_USER0)
|
||||
omx_flags |= 1<<28;
|
||||
if (flags & MMAL_BUFFER_HEADER_FLAG_USER1)
|
||||
omx_flags |= 1<<29;
|
||||
if (flags & MMAL_BUFFER_HEADER_FLAG_USER2)
|
||||
omx_flags |= 1<<30;
|
||||
if (flags & MMAL_BUFFER_HEADER_FLAG_USER3)
|
||||
omx_flags |= 1<<31;
|
||||
|
||||
return omx_flags;
|
||||
}
|
||||
|
||||
uint32_t mmalil_buffer_flags_to_mmal(OMX_U32 flags)
|
||||
{
|
||||
uint32_t mmal_flags = 0;
|
||||
|
||||
if (flags & OMX_BUFFERFLAG_SYNCFRAME)
|
||||
mmal_flags |= MMAL_BUFFER_HEADER_FLAG_KEYFRAME;
|
||||
if (flags & OMX_BUFFERFLAG_ENDOFFRAME)
|
||||
mmal_flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;
|
||||
if (flags & OMX_BUFFERFLAG_EOS)
|
||||
mmal_flags |= MMAL_BUFFER_HEADER_FLAG_EOS;
|
||||
if (flags & OMX_BUFFERFLAG_CODECCONFIG)
|
||||
mmal_flags |= MMAL_BUFFER_HEADER_FLAG_CONFIG;
|
||||
if (flags & OMX_BUFFERFLAG_DISCONTINUITY)
|
||||
mmal_flags |= MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY;
|
||||
if (flags & OMX_BUFFERFLAG_CODECSIDEINFO)
|
||||
mmal_flags |= MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO;
|
||||
if (flags & OMX_BUFFERFLAG_CAPTURE_PREVIEW)
|
||||
mmal_flags |= MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT;
|
||||
if (flags & OMX_BUFFERFLAG_DATACORRUPT)
|
||||
mmal_flags |= MMAL_BUFFER_HEADER_FLAG_CORRUPTED;
|
||||
if (flags & OMX_BUFFERFLAG_DECODEONLY)
|
||||
mmal_flags |= MMAL_BUFFER_HEADER_FLAG_DECODEONLY;
|
||||
if (flags & 1<<28)
|
||||
mmal_flags |= MMAL_BUFFER_HEADER_FLAG_USER0;
|
||||
if (flags & 1<<29)
|
||||
mmal_flags |= MMAL_BUFFER_HEADER_FLAG_USER1;
|
||||
if (flags & 1<<30)
|
||||
mmal_flags |= MMAL_BUFFER_HEADER_FLAG_USER2;
|
||||
if (flags & 1<<31)
|
||||
mmal_flags |= MMAL_BUFFER_HEADER_FLAG_USER3;
|
||||
|
||||
return mmal_flags;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void mmalil_buffer_header_to_omx(OMX_BUFFERHEADERTYPE *omx, MMAL_BUFFER_HEADER_T *mmal)
|
||||
{
|
||||
omx->pBuffer = mmal->data;
|
||||
omx->nAllocLen = mmal->alloc_size;
|
||||
omx->nFilledLen = mmal->length;
|
||||
omx->nOffset = mmal->offset;
|
||||
omx->nFlags = mmalil_buffer_flags_to_omx(mmal->flags);
|
||||
omx->nTimeStamp = omx_ticks_from_s64(mmal->pts);
|
||||
if (mmal->pts == MMAL_TIME_UNKNOWN)
|
||||
{
|
||||
omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
|
||||
omx->nTimeStamp = omx_ticks_from_s64(0);
|
||||
}
|
||||
}
|
||||
|
||||
void mmalil_buffer_header_to_mmal(MMAL_BUFFER_HEADER_T *mmal, OMX_BUFFERHEADERTYPE *omx)
|
||||
{
|
||||
mmal->cmd = 0;
|
||||
mmal->data = omx->pBuffer;
|
||||
mmal->alloc_size = omx->nAllocLen;
|
||||
mmal->length = omx->nFilledLen;
|
||||
mmal->offset = omx->nOffset;
|
||||
mmal->pts = omx_ticks_to_s64(omx->nTimeStamp);
|
||||
if (omx->nFlags & OMX_BUFFERFLAG_TIME_UNKNOWN)
|
||||
mmal->pts = MMAL_TIME_UNKNOWN;
|
||||
mmal->dts = MMAL_TIME_UNKNOWN;
|
||||
mmal->flags = mmalil_buffer_flags_to_mmal(omx->nFlags);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static struct {
|
||||
MMAL_ES_TYPE_T type;
|
||||
OMX_PORTDOMAINTYPE domain;
|
||||
} mmal_omx_es_type_table[] =
|
||||
{
|
||||
{MMAL_ES_TYPE_VIDEO, OMX_PortDomainVideo},
|
||||
{MMAL_ES_TYPE_VIDEO, OMX_PortDomainImage},
|
||||
{MMAL_ES_TYPE_AUDIO, OMX_PortDomainAudio},
|
||||
{MMAL_ES_TYPE_UNKNOWN, OMX_PortDomainMax}
|
||||
};
|
||||
|
||||
OMX_PORTDOMAINTYPE mmalil_es_type_to_omx_domain(MMAL_ES_TYPE_T type)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_es_type_table[i].type != MMAL_ES_TYPE_UNKNOWN; i++)
|
||||
if(mmal_omx_es_type_table[i].type == type) break;
|
||||
return mmal_omx_es_type_table[i].domain;
|
||||
}
|
||||
|
||||
MMAL_ES_TYPE_T mmalil_omx_domain_to_es_type(OMX_PORTDOMAINTYPE domain)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_es_type_table[i].type != MMAL_ES_TYPE_UNKNOWN; i++)
|
||||
if(mmal_omx_es_type_table[i].domain == domain) break;
|
||||
return mmal_omx_es_type_table[i].type;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static struct {
|
||||
uint32_t encoding;
|
||||
OMX_AUDIO_CODINGTYPE coding;
|
||||
} mmal_omx_audio_coding_table[] =
|
||||
{
|
||||
{MMAL_ENCODING_MP4A, OMX_AUDIO_CodingAAC},
|
||||
{MMAL_ENCODING_MPGA, OMX_AUDIO_CodingMP3},
|
||||
{MMAL_ENCODING_WMA2, OMX_AUDIO_CodingWMA},
|
||||
{MMAL_ENCODING_WMA1, OMX_AUDIO_CodingWMA},
|
||||
{MMAL_ENCODING_AMRNB, OMX_AUDIO_CodingAMR},
|
||||
{MMAL_ENCODING_AMRWB, OMX_AUDIO_CodingAMR},
|
||||
{MMAL_ENCODING_AMRWBP, OMX_AUDIO_CodingAMR},
|
||||
{MMAL_ENCODING_VORBIS, OMX_AUDIO_CodingVORBIS},
|
||||
{MMAL_ENCODING_ALAW, OMX_AUDIO_CodingPCM},
|
||||
{MMAL_ENCODING_MULAW, OMX_AUDIO_CodingPCM},
|
||||
{MMAL_ENCODING_PCM_SIGNED_LE, OMX_AUDIO_CodingPCM},
|
||||
{MMAL_ENCODING_PCM_UNSIGNED_LE,OMX_AUDIO_CodingPCM},
|
||||
{MMAL_ENCODING_PCM_SIGNED_BE, OMX_AUDIO_CodingPCM},
|
||||
{MMAL_ENCODING_PCM_UNSIGNED_BE,OMX_AUDIO_CodingPCM},
|
||||
{MMAL_ENCODING_AC3, OMX_AUDIO_CodingDDP},
|
||||
{MMAL_ENCODING_EAC3, OMX_AUDIO_CodingDDP},
|
||||
{MMAL_ENCODING_DTS, OMX_AUDIO_CodingDTS},
|
||||
{MMAL_ENCODING_UNKNOWN, OMX_AUDIO_CodingUnused}
|
||||
};
|
||||
|
||||
uint32_t mmalil_omx_audio_coding_to_encoding(OMX_AUDIO_CODINGTYPE coding)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_audio_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++)
|
||||
if(mmal_omx_audio_coding_table[i].coding == coding) break;
|
||||
return mmal_omx_audio_coding_table[i].encoding;
|
||||
}
|
||||
|
||||
OMX_AUDIO_CODINGTYPE mmalil_encoding_to_omx_audio_coding(uint32_t encoding)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_audio_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++)
|
||||
if(mmal_omx_audio_coding_table[i].encoding == encoding) break;
|
||||
return mmal_omx_audio_coding_table[i].coding;
|
||||
}
|
||||
|
||||
static struct {
|
||||
OMX_AUDIO_CODINGTYPE coding;
|
||||
OMX_INDEXTYPE index;
|
||||
unsigned int size;
|
||||
} mmal_omx_audio_format_table[] =
|
||||
{
|
||||
{OMX_AUDIO_CodingPCM, OMX_IndexParamAudioPcm, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)},
|
||||
{OMX_AUDIO_CodingADPCM, OMX_IndexParamAudioAdpcm, sizeof(OMX_AUDIO_PARAM_ADPCMTYPE)},
|
||||
{OMX_AUDIO_CodingAMR, OMX_IndexParamAudioAmr, sizeof(OMX_AUDIO_PARAM_AMRTYPE)},
|
||||
{OMX_AUDIO_CodingGSMFR, OMX_IndexParamAudioGsm_FR, sizeof(OMX_AUDIO_PARAM_GSMFRTYPE)},
|
||||
{OMX_AUDIO_CodingGSMEFR, OMX_IndexParamAudioGsm_EFR, sizeof(OMX_AUDIO_PARAM_GSMEFRTYPE)},
|
||||
{OMX_AUDIO_CodingGSMHR, OMX_IndexParamAudioGsm_HR, sizeof(OMX_AUDIO_PARAM_GSMHRTYPE)},
|
||||
{OMX_AUDIO_CodingPDCFR, OMX_IndexParamAudioPdc_FR, sizeof(OMX_AUDIO_PARAM_PDCFRTYPE)},
|
||||
{OMX_AUDIO_CodingPDCEFR, OMX_IndexParamAudioPdc_EFR, sizeof(OMX_AUDIO_PARAM_PDCEFRTYPE)},
|
||||
{OMX_AUDIO_CodingPDCHR, OMX_IndexParamAudioPdc_HR, sizeof(OMX_AUDIO_PARAM_PDCHRTYPE)},
|
||||
{OMX_AUDIO_CodingTDMAFR, OMX_IndexParamAudioTdma_FR, sizeof(OMX_AUDIO_PARAM_TDMAFRTYPE)},
|
||||
{OMX_AUDIO_CodingTDMAEFR, OMX_IndexParamAudioTdma_EFR, sizeof(OMX_AUDIO_PARAM_TDMAEFRTYPE)},
|
||||
{OMX_AUDIO_CodingQCELP8, OMX_IndexParamAudioQcelp8, sizeof(OMX_AUDIO_PARAM_QCELP8TYPE)},
|
||||
{OMX_AUDIO_CodingQCELP13, OMX_IndexParamAudioQcelp13, sizeof(OMX_AUDIO_PARAM_QCELP13TYPE)},
|
||||
{OMX_AUDIO_CodingEVRC, OMX_IndexParamAudioEvrc, sizeof(OMX_AUDIO_PARAM_EVRCTYPE)},
|
||||
{OMX_AUDIO_CodingSMV, OMX_IndexParamAudioSmv, sizeof(OMX_AUDIO_PARAM_SMVTYPE)},
|
||||
{OMX_AUDIO_CodingG723, OMX_IndexParamAudioG723, sizeof(OMX_AUDIO_PARAM_G723TYPE)},
|
||||
{OMX_AUDIO_CodingG726, OMX_IndexParamAudioG726, sizeof(OMX_AUDIO_PARAM_G726TYPE)},
|
||||
{OMX_AUDIO_CodingG729, OMX_IndexParamAudioG729, sizeof(OMX_AUDIO_PARAM_G729TYPE)},
|
||||
{OMX_AUDIO_CodingAAC, OMX_IndexParamAudioAac, sizeof(OMX_AUDIO_PARAM_AACPROFILETYPE)},
|
||||
{OMX_AUDIO_CodingMP3, OMX_IndexParamAudioMp3, sizeof(OMX_AUDIO_PARAM_MP3TYPE)},
|
||||
{OMX_AUDIO_CodingSBC, OMX_IndexParamAudioSbc, sizeof(OMX_AUDIO_PARAM_SBCTYPE)},
|
||||
{OMX_AUDIO_CodingVORBIS, OMX_IndexParamAudioVorbis, sizeof(OMX_AUDIO_PARAM_VORBISTYPE)},
|
||||
{OMX_AUDIO_CodingWMA, OMX_IndexParamAudioWma, sizeof(OMX_AUDIO_PARAM_WMATYPE)},
|
||||
{OMX_AUDIO_CodingRA, OMX_IndexParamAudioRa, sizeof(OMX_AUDIO_PARAM_RATYPE)},
|
||||
{OMX_AUDIO_CodingMIDI, OMX_IndexParamAudioMidi, sizeof(OMX_AUDIO_PARAM_MIDITYPE)},
|
||||
{OMX_AUDIO_CodingDDP, OMX_IndexParamAudioDdp, sizeof(OMX_AUDIO_PARAM_DDPTYPE)},
|
||||
{OMX_AUDIO_CodingDTS, OMX_IndexParamAudioDts, sizeof(OMX_AUDIO_PARAM_DTSTYPE)},
|
||||
{OMX_AUDIO_CodingUnused, 0, 0}
|
||||
};
|
||||
|
||||
OMX_AUDIO_CODINGTYPE mmalil_omx_audio_param_index_to_coding(OMX_INDEXTYPE index)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_audio_format_table[i].coding != OMX_AUDIO_CodingUnused; i++)
|
||||
if(mmal_omx_audio_format_table[i].index == index) break;
|
||||
|
||||
return mmal_omx_audio_format_table[i].coding;
|
||||
}
|
||||
|
||||
OMX_INDEXTYPE mmalil_omx_audio_param_index(OMX_AUDIO_CODINGTYPE coding, OMX_U32 *size)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_audio_format_table[i].coding != OMX_AUDIO_CodingUnused; i++)
|
||||
if(mmal_omx_audio_format_table[i].coding == coding) break;
|
||||
|
||||
if(size) *size = mmal_omx_audio_format_table[i].size;
|
||||
return mmal_omx_audio_format_table[i].index;
|
||||
}
|
||||
|
||||
MMAL_STATUS_T mmalil_omx_default_channel_mapping(OMX_AUDIO_CHANNELTYPE *channel_mapping, unsigned int nchannels)
|
||||
{
|
||||
static const OMX_AUDIO_CHANNELTYPE default_mapping[][8] = {
|
||||
{OMX_AUDIO_ChannelNone},
|
||||
{OMX_AUDIO_ChannelCF},
|
||||
{OMX_AUDIO_ChannelLF, OMX_AUDIO_ChannelRF},
|
||||
{OMX_AUDIO_ChannelLF, OMX_AUDIO_ChannelRF, OMX_AUDIO_ChannelCF},
|
||||
{OMX_AUDIO_ChannelLF, OMX_AUDIO_ChannelRF, OMX_AUDIO_ChannelCF,
|
||||
OMX_AUDIO_ChannelCS},
|
||||
{OMX_AUDIO_ChannelLF, OMX_AUDIO_ChannelRF, OMX_AUDIO_ChannelCF,
|
||||
OMX_AUDIO_ChannelLR, OMX_AUDIO_ChannelRR},
|
||||
{OMX_AUDIO_ChannelLF, OMX_AUDIO_ChannelRF, OMX_AUDIO_ChannelCF,
|
||||
OMX_AUDIO_ChannelLFE, OMX_AUDIO_ChannelLR, OMX_AUDIO_ChannelRR},
|
||||
{OMX_AUDIO_ChannelLF, OMX_AUDIO_ChannelRF, OMX_AUDIO_ChannelCF,
|
||||
OMX_AUDIO_ChannelLFE, OMX_AUDIO_ChannelLR, OMX_AUDIO_ChannelRR,
|
||||
OMX_AUDIO_ChannelCS},
|
||||
{OMX_AUDIO_ChannelLF, OMX_AUDIO_ChannelRF, OMX_AUDIO_ChannelCF,
|
||||
OMX_AUDIO_ChannelLFE, OMX_AUDIO_ChannelLR, OMX_AUDIO_ChannelRR,
|
||||
OMX_AUDIO_ChannelLS, OMX_AUDIO_ChannelRS}
|
||||
};
|
||||
|
||||
if (!nchannels || nchannels + 1 >= MMAL_COUNTOF(default_mapping))
|
||||
return MMAL_EINVAL;
|
||||
|
||||
memcpy(channel_mapping, default_mapping[nchannels],
|
||||
sizeof(default_mapping[0][0]) * nchannels);
|
||||
return MMAL_SUCCESS;
|
||||
}
|
||||
|
||||
MMAL_FOURCC_T mmalil_omx_audio_param_to_format(MMAL_ES_FORMAT_T *format,
|
||||
OMX_AUDIO_CODINGTYPE coding, OMX_FORMAT_PARAM_TYPE *param)
|
||||
{
|
||||
MMAL_AUDIO_FORMAT_T *audio = &format->es->audio;
|
||||
format->encoding = mmalil_omx_audio_coding_to_encoding(coding);
|
||||
format->encoding_variant = 0;
|
||||
|
||||
switch(coding)
|
||||
{
|
||||
case OMX_AUDIO_CodingPCM:
|
||||
audio->channels = param->pcm.nChannels;
|
||||
audio->sample_rate = param->pcm.nSamplingRate;
|
||||
audio->bits_per_sample = param->pcm.nBitPerSample;
|
||||
if(param->pcm.ePCMMode == OMX_AUDIO_PCMModeLinear && param->pcm.bInterleaved)
|
||||
{
|
||||
if(param->pcm.eEndian == OMX_EndianBig &&
|
||||
param->pcm.eNumData == OMX_NumericalDataSigned)
|
||||
format->encoding = MMAL_ENCODING_PCM_SIGNED_BE;
|
||||
else if(param->pcm.eEndian == OMX_EndianLittle &&
|
||||
param->pcm.eNumData == OMX_NumericalDataSigned)
|
||||
format->encoding = MMAL_ENCODING_PCM_SIGNED_LE;
|
||||
if(param->pcm.eEndian == OMX_EndianBig &&
|
||||
param->pcm.eNumData == OMX_NumericalDataUnsigned)
|
||||
format->encoding = MMAL_ENCODING_PCM_UNSIGNED_BE;
|
||||
if(param->pcm.eEndian == OMX_EndianLittle &&
|
||||
param->pcm.eNumData == OMX_NumericalDataUnsigned)
|
||||
format->encoding = MMAL_ENCODING_PCM_UNSIGNED_LE;
|
||||
}
|
||||
else if(param->pcm.ePCMMode == OMX_AUDIO_PCMModeALaw)
|
||||
format->encoding = MMAL_ENCODING_ALAW;
|
||||
else if(param->pcm.ePCMMode == OMX_AUDIO_PCMModeMULaw)
|
||||
format->encoding = MMAL_ENCODING_MULAW;
|
||||
break;
|
||||
case OMX_AUDIO_CodingAAC:
|
||||
audio->channels = param->aac.nChannels;
|
||||
audio->sample_rate = param->aac.nSampleRate;
|
||||
format->bitrate = param->aac.nBitRate;
|
||||
switch(param->aac.eAACStreamFormat)
|
||||
{
|
||||
case OMX_AUDIO_AACStreamFormatMP2ADTS:
|
||||
case OMX_AUDIO_AACStreamFormatMP4ADTS:
|
||||
format->encoding = MMAL_ENCODING_MP4A;
|
||||
format->encoding_variant = MMAL_ENCODING_VARIANT_MP4A_ADTS;
|
||||
break;
|
||||
case OMX_AUDIO_AACStreamFormatMP4FF:
|
||||
case OMX_AUDIO_AACStreamFormatRAW:
|
||||
format->encoding = MMAL_ENCODING_MP4A;
|
||||
format->encoding_variant = MMAL_ENCODING_VARIANT_MP4A_DEFAULT;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
case OMX_AUDIO_CodingMP3:
|
||||
format->encoding = MMAL_ENCODING_MPGA;
|
||||
audio->channels = param->mp3.nChannels;
|
||||
audio->sample_rate = param->mp3.nSampleRate;
|
||||
format->bitrate = param->mp3.nBitRate;
|
||||
break;
|
||||
case OMX_AUDIO_CodingWMA:
|
||||
audio->channels = param->wma.nChannels;
|
||||
audio->sample_rate = param->wma.nSamplingRate;
|
||||
audio->block_align = param->wma.nBlockAlign;
|
||||
format->bitrate = param->wma.nBitRate;
|
||||
switch(param->wma.eFormat)
|
||||
{
|
||||
case OMX_AUDIO_WMAFormat7:
|
||||
format->encoding = MMAL_ENCODING_WMA1;
|
||||
break;
|
||||
case OMX_AUDIO_WMAFormat8:
|
||||
case OMX_AUDIO_WMAFormat9:
|
||||
format->encoding = MMAL_ENCODING_WMA2;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
case OMX_AUDIO_CodingVORBIS:
|
||||
audio->channels = param->vorbis.nChannels;
|
||||
audio->sample_rate = param->vorbis.nSampleRate;
|
||||
format->bitrate = param->vorbis.nBitRate;
|
||||
break;
|
||||
case OMX_AUDIO_CodingAMR:
|
||||
audio->channels = param->amr.nChannels;
|
||||
audio->sample_rate = 8000;
|
||||
format->bitrate = param->amr.nBitRate;
|
||||
if(param->amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0 &&
|
||||
param->amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7)
|
||||
format->encoding = MMAL_ENCODING_AMRNB;
|
||||
if(param->amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0 &&
|
||||
param->amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8)
|
||||
format->encoding = MMAL_ENCODING_AMRWB;
|
||||
break;
|
||||
case OMX_AUDIO_CodingDDP:
|
||||
audio->channels = param->ddp.nChannels;
|
||||
audio->sample_rate = param->ddp.nSampleRate;
|
||||
if(param->ddp.eBitStreamId > OMX_AUDIO_DDPBitStreamIdAC3)
|
||||
format->encoding = MMAL_ENCODING_EAC3;
|
||||
break;
|
||||
case OMX_AUDIO_CodingDTS:
|
||||
audio->channels = param->dts.nChannels;
|
||||
audio->sample_rate = param->dts.nSampleRate;
|
||||
audio->block_align = param->dts.nDtsFrameSizeBytes;
|
||||
break;
|
||||
|
||||
case OMX_AUDIO_CodingADPCM:
|
||||
case OMX_AUDIO_CodingGSMFR:
|
||||
case OMX_AUDIO_CodingGSMEFR:
|
||||
case OMX_AUDIO_CodingGSMHR:
|
||||
case OMX_AUDIO_CodingPDCFR:
|
||||
case OMX_AUDIO_CodingPDCEFR:
|
||||
case OMX_AUDIO_CodingPDCHR:
|
||||
case OMX_AUDIO_CodingTDMAFR:
|
||||
case OMX_AUDIO_CodingTDMAEFR:
|
||||
case OMX_AUDIO_CodingQCELP8:
|
||||
case OMX_AUDIO_CodingQCELP13:
|
||||
case OMX_AUDIO_CodingEVRC:
|
||||
case OMX_AUDIO_CodingSMV:
|
||||
case OMX_AUDIO_CodingG711:
|
||||
case OMX_AUDIO_CodingG723:
|
||||
case OMX_AUDIO_CodingG726:
|
||||
case OMX_AUDIO_CodingG729:
|
||||
case OMX_AUDIO_CodingSBC:
|
||||
case OMX_AUDIO_CodingRA:
|
||||
case OMX_AUDIO_CodingMIDI:
|
||||
default:
|
||||
vcos_assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return format->encoding;
|
||||
}
|
||||
|
||||
OMX_AUDIO_CODINGTYPE mmalil_format_to_omx_audio_param(OMX_FORMAT_PARAM_TYPE *param,
|
||||
OMX_INDEXTYPE *param_index, MMAL_ES_FORMAT_T *format)
|
||||
{
|
||||
MMAL_AUDIO_FORMAT_T *audio = &format->es->audio;
|
||||
OMX_AUDIO_CODINGTYPE coding = mmalil_encoding_to_omx_audio_coding(format->encoding);
|
||||
OMX_U32 size = 0;
|
||||
OMX_INDEXTYPE index = mmalil_omx_audio_param_index(coding, &size);
|
||||
|
||||
if(param_index) *param_index = index;
|
||||
memset(param, 0, size);
|
||||
param->common.nSize = size;
|
||||
|
||||
switch(coding)
|
||||
{
|
||||
case OMX_AUDIO_CodingPCM:
|
||||
param->pcm.nChannels = audio->channels;
|
||||
param->pcm.nSamplingRate = audio->sample_rate;
|
||||
param->pcm.nBitPerSample = audio->bits_per_sample;
|
||||
mmalil_omx_default_channel_mapping(param->pcm.eChannelMapping, audio->channels);
|
||||
if(format->encoding == MMAL_ENCODING_PCM_SIGNED_BE ||
|
||||
format->encoding == MMAL_ENCODING_PCM_SIGNED_LE ||
|
||||
format->encoding == MMAL_ENCODING_PCM_UNSIGNED_BE ||
|
||||
format->encoding == MMAL_ENCODING_PCM_UNSIGNED_LE)
|
||||
{
|
||||
param->pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
|
||||
param->pcm.bInterleaved = OMX_TRUE;
|
||||
param->pcm.eEndian = OMX_EndianLittle;
|
||||
param->pcm.eNumData = OMX_NumericalDataSigned;
|
||||
if(format->encoding == MMAL_ENCODING_PCM_SIGNED_BE ||
|
||||
format->encoding == MMAL_ENCODING_PCM_UNSIGNED_BE)
|
||||
param->pcm.eEndian = OMX_EndianBig;
|
||||
if(format->encoding == MMAL_ENCODING_PCM_UNSIGNED_LE ||
|
||||
format->encoding == MMAL_ENCODING_PCM_UNSIGNED_BE)
|
||||
param->pcm.eNumData = OMX_NumericalDataUnsigned;
|
||||
}
|
||||
else if(format->encoding == MMAL_ENCODING_ALAW)
|
||||
param->pcm.ePCMMode = OMX_AUDIO_PCMModeALaw;
|
||||
else if(format->encoding == MMAL_ENCODING_MULAW)
|
||||
param->pcm.ePCMMode = OMX_AUDIO_PCMModeMULaw;
|
||||
break;
|
||||
case OMX_AUDIO_CodingAAC:
|
||||
param->aac.nChannels = audio->channels;
|
||||
param->aac.nSampleRate = audio->sample_rate;
|
||||
param->aac.nBitRate = format->bitrate;
|
||||
switch(format->encoding_variant)
|
||||
{
|
||||
case MMAL_ENCODING_VARIANT_MP4A_ADTS:
|
||||
param->aac.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
|
||||
break;
|
||||
case MMAL_ENCODING_VARIANT_MP4A_DEFAULT:
|
||||
param->aac.eAACStreamFormat = OMX_AUDIO_AACStreamFormatRAW;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
case OMX_AUDIO_CodingMP3:
|
||||
param->mp3.nChannels = audio->channels;
|
||||
param->mp3.nSampleRate = audio->sample_rate;
|
||||
param->mp3.nBitRate = format->bitrate;
|
||||
break;
|
||||
case OMX_AUDIO_CodingWMA:
|
||||
param->wma.nChannels = audio->channels;
|
||||
param->wma.nSamplingRate = audio->sample_rate;
|
||||
param->wma.nBlockAlign = audio->block_align;
|
||||
param->wma.nBitRate = format->bitrate;
|
||||
switch(format->encoding)
|
||||
{
|
||||
case MMAL_ENCODING_WMA1:
|
||||
param->wma.eFormat = OMX_AUDIO_WMAFormat7;
|
||||
break;
|
||||
case MMAL_ENCODING_WMA2:
|
||||
param->wma.eFormat = OMX_AUDIO_WMAFormat8;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
case OMX_AUDIO_CodingVORBIS:
|
||||
param->vorbis.nChannels = audio->channels;
|
||||
param->vorbis.nSampleRate = audio->sample_rate;
|
||||
param->vorbis.nBitRate = format->bitrate;
|
||||
break;
|
||||
case OMX_AUDIO_CodingAMR:
|
||||
param->amr.nChannels = audio->channels;
|
||||
param->amr.nBitRate = format->bitrate;
|
||||
if(format->encoding == MMAL_ENCODING_AMRNB)
|
||||
param->amr.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0;
|
||||
if(format->encoding == MMAL_ENCODING_AMRWB)
|
||||
param->amr.eAMRBandMode = OMX_AUDIO_AMRBandModeWB0;
|
||||
break;
|
||||
case OMX_AUDIO_CodingDDP:
|
||||
param->ddp.nChannels = audio->channels;
|
||||
param->ddp.nSampleRate = audio->sample_rate;
|
||||
param->ddp.eBitStreamId = OMX_AUDIO_DDPBitStreamIdAC3;
|
||||
if(format->encoding == MMAL_ENCODING_EAC3)
|
||||
param->ddp.eBitStreamId = OMX_AUDIO_DDPBitStreamIdEAC3;
|
||||
param->ddp.eBitStreamMode = 0;
|
||||
param->ddp.eDolbySurroundMode = 0;
|
||||
mmalil_omx_default_channel_mapping(param->ddp.eChannelMapping, audio->channels);
|
||||
break;
|
||||
case OMX_AUDIO_CodingDTS:
|
||||
param->dts.nChannels = audio->channels;
|
||||
param->dts.nSampleRate = audio->sample_rate;
|
||||
param->dts.nDtsFrameSizeBytes = audio->block_align;
|
||||
param->dts.nDtsType = 1;
|
||||
param->dts.nFormat = 0;
|
||||
mmalil_omx_default_channel_mapping(param->dts.eChannelMapping, audio->channels);
|
||||
break;
|
||||
case OMX_AUDIO_CodingADPCM:
|
||||
case OMX_AUDIO_CodingGSMFR:
|
||||
case OMX_AUDIO_CodingGSMEFR:
|
||||
case OMX_AUDIO_CodingGSMHR:
|
||||
case OMX_AUDIO_CodingPDCFR:
|
||||
case OMX_AUDIO_CodingPDCEFR:
|
||||
case OMX_AUDIO_CodingPDCHR:
|
||||
case OMX_AUDIO_CodingTDMAFR:
|
||||
case OMX_AUDIO_CodingTDMAEFR:
|
||||
case OMX_AUDIO_CodingQCELP8:
|
||||
case OMX_AUDIO_CodingQCELP13:
|
||||
case OMX_AUDIO_CodingEVRC:
|
||||
case OMX_AUDIO_CodingSMV:
|
||||
case OMX_AUDIO_CodingG711:
|
||||
case OMX_AUDIO_CodingG723:
|
||||
case OMX_AUDIO_CodingG726:
|
||||
case OMX_AUDIO_CodingG729:
|
||||
case OMX_AUDIO_CodingSBC:
|
||||
case OMX_AUDIO_CodingRA:
|
||||
case OMX_AUDIO_CodingMIDI:
|
||||
default:
|
||||
vcos_assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return coding;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static struct {
|
||||
uint32_t encoding;
|
||||
OMX_VIDEO_CODINGTYPE coding;
|
||||
} mmal_omx_video_coding_table[] =
|
||||
{
|
||||
{MMAL_ENCODING_H264, OMX_VIDEO_CodingAVC},
|
||||
{MMAL_ENCODING_MP4V, OMX_VIDEO_CodingMPEG4},
|
||||
{MMAL_ENCODING_MP2V, OMX_VIDEO_CodingMPEG2},
|
||||
{MMAL_ENCODING_MP1V, OMX_VIDEO_CodingMPEG2},
|
||||
{MMAL_ENCODING_H263, OMX_VIDEO_CodingH263},
|
||||
{MMAL_ENCODING_WMV3, OMX_VIDEO_CodingWMV},
|
||||
{MMAL_ENCODING_WMV2, OMX_VIDEO_CodingWMV},
|
||||
{MMAL_ENCODING_WMV1, OMX_VIDEO_CodingWMV},
|
||||
{MMAL_ENCODING_WVC1, OMX_VIDEO_CodingWMV},
|
||||
{MMAL_ENCODING_VP6, OMX_VIDEO_CodingVP6},
|
||||
{MMAL_ENCODING_VP7, OMX_VIDEO_CodingVP7},
|
||||
{MMAL_ENCODING_VP8, OMX_VIDEO_CodingVP8},
|
||||
{MMAL_ENCODING_SPARK, OMX_VIDEO_CodingSorenson},
|
||||
{MMAL_ENCODING_THEORA, OMX_VIDEO_CodingTheora},
|
||||
{MMAL_ENCODING_MJPEG, OMX_VIDEO_CodingMJPEG},
|
||||
{MMAL_ENCODING_UNKNOWN, OMX_VIDEO_CodingUnused}
|
||||
};
|
||||
|
||||
uint32_t mmalil_omx_video_coding_to_encoding(OMX_VIDEO_CODINGTYPE coding)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_video_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++)
|
||||
if(mmal_omx_video_coding_table[i].coding == coding) break;
|
||||
return mmal_omx_video_coding_table[i].encoding;
|
||||
}
|
||||
|
||||
OMX_VIDEO_CODINGTYPE mmalil_encoding_to_omx_video_coding(uint32_t encoding)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_video_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++)
|
||||
if(mmal_omx_video_coding_table[i].encoding == encoding) break;
|
||||
return mmal_omx_video_coding_table[i].coding;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static struct {
|
||||
uint32_t encoding;
|
||||
OMX_IMAGE_CODINGTYPE coding;
|
||||
} mmal_omx_image_coding_table[] =
|
||||
{
|
||||
{MMAL_ENCODING_JPEG, OMX_IMAGE_CodingJPEG},
|
||||
{MMAL_ENCODING_GIF, OMX_IMAGE_CodingGIF},
|
||||
{MMAL_ENCODING_PNG, OMX_IMAGE_CodingPNG},
|
||||
{MMAL_ENCODING_BMP, OMX_IMAGE_CodingBMP},
|
||||
{MMAL_ENCODING_TGA, OMX_IMAGE_CodingTGA},
|
||||
{MMAL_ENCODING_PPM, OMX_IMAGE_CodingPPM},
|
||||
{MMAL_ENCODING_UNKNOWN, OMX_IMAGE_CodingUnused}
|
||||
};
|
||||
|
||||
uint32_t mmalil_omx_image_coding_to_encoding(OMX_IMAGE_CODINGTYPE coding)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_image_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++)
|
||||
if(mmal_omx_image_coding_table[i].coding == coding) break;
|
||||
return mmal_omx_image_coding_table[i].encoding;
|
||||
}
|
||||
|
||||
OMX_IMAGE_CODINGTYPE mmalil_encoding_to_omx_image_coding(uint32_t encoding)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_image_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++)
|
||||
if(mmal_omx_image_coding_table[i].encoding == encoding) break;
|
||||
return mmal_omx_image_coding_table[i].coding;
|
||||
}
|
||||
|
||||
uint32_t mmalil_omx_coding_to_encoding(uint32_t encoding, OMX_PORTDOMAINTYPE domain)
|
||||
{
|
||||
if(domain == OMX_PortDomainVideo)
|
||||
return mmalil_omx_video_coding_to_encoding((OMX_VIDEO_CODINGTYPE)encoding);
|
||||
else if(domain == OMX_PortDomainAudio)
|
||||
return mmalil_omx_audio_coding_to_encoding((OMX_AUDIO_CODINGTYPE)encoding);
|
||||
else if(domain == OMX_PortDomainImage)
|
||||
return mmalil_omx_image_coding_to_encoding((OMX_IMAGE_CODINGTYPE)encoding);
|
||||
else
|
||||
return MMAL_ENCODING_UNKNOWN;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static struct {
|
||||
uint32_t encoding;
|
||||
OMX_COLOR_FORMATTYPE coding;
|
||||
} mmal_omx_colorformat_coding_table[] =
|
||||
{
|
||||
{MMAL_ENCODING_I420, OMX_COLOR_FormatYUV420PackedPlanar},
|
||||
{MMAL_ENCODING_I422, OMX_COLOR_FormatYUV422PackedPlanar},
|
||||
{MMAL_ENCODING_I420_SLICE, OMX_COLOR_FormatYUV420PackedPlanar},
|
||||
{MMAL_ENCODING_I422_SLICE, OMX_COLOR_FormatYUV422PackedPlanar},
|
||||
{MMAL_ENCODING_I420, OMX_COLOR_FormatYUV420Planar},
|
||||
{MMAL_ENCODING_YV12, OMX_COLOR_FormatYVU420PackedPlanar},
|
||||
{MMAL_ENCODING_NV12, OMX_COLOR_FormatYUV420PackedSemiPlanar},
|
||||
{MMAL_ENCODING_NV12, OMX_COLOR_FormatYUV420SemiPlanar},
|
||||
{MMAL_ENCODING_NV21, OMX_COLOR_FormatYVU420PackedSemiPlanar},
|
||||
{MMAL_ENCODING_YUVUV128, OMX_COLOR_FormatYUVUV128},
|
||||
{MMAL_ENCODING_YUYV, OMX_COLOR_FormatYCbYCr},
|
||||
{MMAL_ENCODING_YVYU, OMX_COLOR_FormatYCrYCb},
|
||||
{MMAL_ENCODING_UYVY, OMX_COLOR_FormatCbYCrY},
|
||||
{MMAL_ENCODING_VYUY, OMX_COLOR_FormatCrYCbY},
|
||||
{MMAL_ENCODING_RGB16, OMX_COLOR_Format16bitRGB565},
|
||||
{MMAL_ENCODING_BGR24, OMX_COLOR_Format24bitRGB888},
|
||||
{MMAL_ENCODING_BGRA, OMX_COLOR_Format32bitARGB8888},
|
||||
{MMAL_ENCODING_BGR16, OMX_COLOR_Format16bitBGR565},
|
||||
{MMAL_ENCODING_RGB24, OMX_COLOR_Format24bitBGR888},
|
||||
{MMAL_ENCODING_ARGB, OMX_COLOR_Format32bitBGRA8888},
|
||||
{MMAL_ENCODING_RGBA, OMX_COLOR_Format32bitABGR8888},
|
||||
{MMAL_ENCODING_EGL_IMAGE, OMX_COLOR_FormatBRCMEGL},
|
||||
{MMAL_ENCODING_OPAQUE, OMX_COLOR_FormatBRCMOpaque},
|
||||
{MMAL_ENCODING_UNKNOWN, OMX_COLOR_FormatUnused}
|
||||
};
|
||||
|
||||
uint32_t mmalil_omx_color_format_to_encoding(OMX_COLOR_FORMATTYPE coding)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_colorformat_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++)
|
||||
if(mmal_omx_colorformat_coding_table[i].coding == coding) break;
|
||||
return mmal_omx_colorformat_coding_table[i].encoding;
|
||||
}
|
||||
|
||||
OMX_COLOR_FORMATTYPE mmalil_encoding_to_omx_color_format(uint32_t encoding)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_colorformat_coding_table[i].encoding != MMAL_ENCODING_UNKNOWN; i++)
|
||||
if(mmal_omx_colorformat_coding_table[i].encoding == encoding) break;
|
||||
return mmal_omx_colorformat_coding_table[i].coding;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static struct {
|
||||
uint32_t mmal;
|
||||
OMX_COLORSPACETYPE omx;
|
||||
} mmal_omx_colorspace_coding_table[] =
|
||||
{
|
||||
{MMAL_COLOR_SPACE_ITUR_BT601, OMX_COLORSPACE_ITU_R_BT601},
|
||||
{MMAL_COLOR_SPACE_ITUR_BT709, OMX_COLORSPACE_ITU_R_BT709},
|
||||
{MMAL_COLOR_SPACE_JPEG_JFIF, OMX_COLORSPACE_JPEG_JFIF},
|
||||
{MMAL_COLOR_SPACE_FCC, OMX_COLORSPACE_FCC},
|
||||
{MMAL_COLOR_SPACE_SMPTE240M, OMX_COLORSPACE_SMPTE240M},
|
||||
{MMAL_COLOR_SPACE_BT470_2_M, OMX_COLORSPACE_BT470_2_M},
|
||||
{MMAL_COLOR_SPACE_BT470_2_BG, OMX_COLORSPACE_BT470_2_BG},
|
||||
{MMAL_COLOR_SPACE_JFIF_Y16_255, OMX_COLORSPACE_JFIF_Y16_255},
|
||||
{MMAL_COLOR_SPACE_UNKNOWN, OMX_COLORSPACE_UNKNOWN}
|
||||
};
|
||||
|
||||
uint32_t mmalil_omx_color_space_to_mmal(OMX_COLORSPACETYPE coding)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_colorspace_coding_table[i].mmal != MMAL_COLOR_SPACE_UNKNOWN; i++)
|
||||
if(mmal_omx_colorspace_coding_table[i].omx == coding) break;
|
||||
return mmal_omx_colorspace_coding_table[i].mmal;
|
||||
}
|
||||
|
||||
OMX_COLORSPACETYPE mmalil_color_space_to_omx(uint32_t coding)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_colorspace_coding_table[i].mmal != MMAL_COLOR_SPACE_UNKNOWN; i++)
|
||||
if(mmal_omx_colorspace_coding_table[i].mmal == coding) break;
|
||||
return mmal_omx_colorspace_coding_table[i].omx;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static struct {
|
||||
uint32_t mmal;
|
||||
OMX_U32 omx;
|
||||
OMX_VIDEO_CODINGTYPE omx_coding;
|
||||
} mmal_omx_video_profile_table[] =
|
||||
{
|
||||
{ MMAL_VIDEO_PROFILE_H263_BASELINE, OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_PROFILE_H263_H320CODING, OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_PROFILE_H263_BACKWARDCOMPATIBLE, OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_PROFILE_H263_ISWV2, OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_PROFILE_H263_ISWV3, OMX_VIDEO_H263ProfileISWV3, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_PROFILE_H263_HIGHCOMPRESSION, OMX_VIDEO_H263ProfileHighCompression, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_PROFILE_H263_INTERNET, OMX_VIDEO_H263ProfileInternet, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_PROFILE_H263_INTERLACE, OMX_VIDEO_H263ProfileInterlace, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_PROFILE_H263_HIGHLATENCY, OMX_VIDEO_H263ProfileHighLatency, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_SIMPLE, OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_SIMPLESCALABLE, OMX_VIDEO_MPEG4ProfileSimpleScalable, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_CORE, OMX_VIDEO_MPEG4ProfileCore, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_MAIN, OMX_VIDEO_MPEG4ProfileMain, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_NBIT, OMX_VIDEO_MPEG4ProfileNbit, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_SCALABLETEXTURE, OMX_VIDEO_MPEG4ProfileScalableTexture, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_SIMPLEFACE, OMX_VIDEO_MPEG4ProfileSimpleFace, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_SIMPLEFBA, OMX_VIDEO_MPEG4ProfileSimpleFBA, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_BASICANIMATED, OMX_VIDEO_MPEG4ProfileBasicAnimated, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_HYBRID, OMX_VIDEO_MPEG4ProfileHybrid, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDREALTIME, OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_CORESCALABLE, OMX_VIDEO_MPEG4ProfileCoreScalable, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCODING, OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCORE, OMX_VIDEO_MPEG4ProfileAdvancedCore, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSCALABLE, OMX_VIDEO_MPEG4ProfileAdvancedScalable, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSIMPLE, OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_PROFILE_H264_BASELINE, OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_PROFILE_H264_MAIN, OMX_VIDEO_AVCProfileMain, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_PROFILE_H264_EXTENDED, OMX_VIDEO_AVCProfileExtended, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_PROFILE_H264_HIGH, OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_PROFILE_H264_HIGH10, OMX_VIDEO_AVCProfileHigh10, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_PROFILE_H264_HIGH422, OMX_VIDEO_AVCProfileHigh422, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_PROFILE_H264_HIGH444, OMX_VIDEO_AVCProfileHigh444, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE, OMX_VIDEO_AVCProfileConstrainedBaseline, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_PROFILE_DUMMY, OMX_VIDEO_AVCProfileMax, OMX_VIDEO_CodingAVC},
|
||||
};
|
||||
|
||||
uint32_t mmalil_omx_video_profile_to_mmal(OMX_U32 profile, OMX_VIDEO_CODINGTYPE coding)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_video_profile_table[i].mmal != MMAL_VIDEO_PROFILE_DUMMY; i++)
|
||||
if(mmal_omx_video_profile_table[i].omx == profile
|
||||
&& mmal_omx_video_profile_table[i].omx_coding == coding) break;
|
||||
return mmal_omx_video_profile_table[i].mmal;
|
||||
}
|
||||
|
||||
OMX_U32 mmalil_video_profile_to_omx(uint32_t profile)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_video_profile_table[i].mmal != MMAL_VIDEO_PROFILE_DUMMY; i++)
|
||||
if(mmal_omx_video_profile_table[i].mmal == profile) break;
|
||||
return mmal_omx_video_profile_table[i].omx;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static struct {
|
||||
uint32_t mmal;
|
||||
OMX_U32 omx;
|
||||
OMX_VIDEO_CODINGTYPE omx_coding;
|
||||
} mmal_omx_video_level_table[] =
|
||||
{
|
||||
{ MMAL_VIDEO_LEVEL_H263_10, OMX_VIDEO_H263Level10, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_LEVEL_H263_20, OMX_VIDEO_H263Level20, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_LEVEL_H263_30, OMX_VIDEO_H263Level30, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_LEVEL_H263_40, OMX_VIDEO_H263Level40, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_LEVEL_H263_45, OMX_VIDEO_H263Level45, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_LEVEL_H263_50, OMX_VIDEO_H263Level50, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_LEVEL_H263_60, OMX_VIDEO_H263Level60, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_LEVEL_H263_70, OMX_VIDEO_H263Level70, OMX_VIDEO_CodingH263},
|
||||
{ MMAL_VIDEO_LEVEL_MP4V_0, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_LEVEL_MP4V_0b, OMX_VIDEO_MPEG4Level0b, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_LEVEL_MP4V_1, OMX_VIDEO_MPEG4Level1, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_LEVEL_MP4V_2, OMX_VIDEO_MPEG4Level2, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_LEVEL_MP4V_3, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_LEVEL_MP4V_4, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_LEVEL_MP4V_4a, OMX_VIDEO_MPEG4Level4a, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_LEVEL_MP4V_5, OMX_VIDEO_MPEG4Level5, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_LEVEL_MP4V_6, OMX_VIDEO_MPEG4Level6, OMX_VIDEO_CodingMPEG4},
|
||||
{ MMAL_VIDEO_LEVEL_H264_1, OMX_VIDEO_AVCLevel1, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_H264_1b, OMX_VIDEO_AVCLevel1b, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_H264_11, OMX_VIDEO_AVCLevel11, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_H264_12, OMX_VIDEO_AVCLevel12, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_H264_13, OMX_VIDEO_AVCLevel13, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_H264_2, OMX_VIDEO_AVCLevel2, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_H264_21, OMX_VIDEO_AVCLevel21, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_H264_22, OMX_VIDEO_AVCLevel22, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_H264_3, OMX_VIDEO_AVCLevel3, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_H264_31, OMX_VIDEO_AVCLevel31, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_H264_32, OMX_VIDEO_AVCLevel32, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_H264_4, OMX_VIDEO_AVCLevel4, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_H264_41, OMX_VIDEO_AVCLevel41, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_H264_42, OMX_VIDEO_AVCLevel42, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_H264_5, OMX_VIDEO_AVCLevel5, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_H264_51, OMX_VIDEO_AVCLevel51, OMX_VIDEO_CodingAVC},
|
||||
{ MMAL_VIDEO_LEVEL_DUMMY, OMX_VIDEO_AVCLevelMax, OMX_VIDEO_CodingMax},
|
||||
};
|
||||
|
||||
uint32_t mmalil_omx_video_level_to_mmal(OMX_U32 level, OMX_VIDEO_CODINGTYPE coding)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_video_level_table[i].mmal != MMAL_VIDEO_LEVEL_DUMMY; i++)
|
||||
if(mmal_omx_video_level_table[i].omx == level
|
||||
&& mmal_omx_video_level_table[i].omx_coding == coding) break;
|
||||
return mmal_omx_video_level_table[i].mmal;
|
||||
}
|
||||
|
||||
OMX_U32 mmalil_video_level_to_omx(uint32_t level)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_video_level_table[i].mmal != MMAL_VIDEO_LEVEL_DUMMY; i++)
|
||||
if(mmal_omx_video_level_table[i].mmal == level) break;
|
||||
return mmal_omx_video_level_table[i].omx;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static struct {
|
||||
MMAL_VIDEO_RATECONTROL_T mmal;
|
||||
OMX_VIDEO_CONTROLRATETYPE omx;
|
||||
} mmal_omx_video_ratecontrol_table[] =
|
||||
{
|
||||
{ MMAL_VIDEO_RATECONTROL_DEFAULT, OMX_Video_ControlRateDisable},
|
||||
{ MMAL_VIDEO_RATECONTROL_VARIABLE, OMX_Video_ControlRateVariable},
|
||||
{ MMAL_VIDEO_RATECONTROL_CONSTANT, OMX_Video_ControlRateConstant},
|
||||
{ MMAL_VIDEO_RATECONTROL_VARIABLE_SKIP_FRAMES, OMX_Video_ControlRateVariableSkipFrames},
|
||||
{ MMAL_VIDEO_RATECONTROL_CONSTANT_SKIP_FRAMES, OMX_Video_ControlRateConstantSkipFrames},
|
||||
{ MMAL_VIDEO_RATECONTROL_DUMMY, OMX_Video_ControlRateMax},
|
||||
};
|
||||
|
||||
MMAL_VIDEO_RATECONTROL_T mmalil_omx_video_ratecontrol_to_mmal(OMX_VIDEO_CONTROLRATETYPE omx)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_video_ratecontrol_table[i].mmal != MMAL_VIDEO_RATECONTROL_DUMMY; i++)
|
||||
if(mmal_omx_video_ratecontrol_table[i].omx == omx) break;
|
||||
return mmal_omx_video_ratecontrol_table[i].mmal;
|
||||
}
|
||||
|
||||
OMX_VIDEO_CONTROLRATETYPE mmalil_video_ratecontrol_to_omx(MMAL_VIDEO_RATECONTROL_T mmal)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_video_ratecontrol_table[i].mmal != MMAL_VIDEO_RATECONTROL_DUMMY; i++)
|
||||
if(mmal_omx_video_ratecontrol_table[i].mmal == mmal) break;
|
||||
return mmal_omx_video_ratecontrol_table[i].omx;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static struct {
|
||||
MMAL_VIDEO_INTRA_REFRESH_T mmal;
|
||||
OMX_VIDEO_INTRAREFRESHTYPE omx;
|
||||
} mmal_omx_video_intrarefresh_table[] =
|
||||
{
|
||||
{ MMAL_VIDEO_INTRA_REFRESH_CYCLIC, OMX_VIDEO_IntraRefreshCyclic},
|
||||
{ MMAL_VIDEO_INTRA_REFRESH_ADAPTIVE, OMX_VIDEO_IntraRefreshAdaptive},
|
||||
{ MMAL_VIDEO_INTRA_REFRESH_BOTH, OMX_VIDEO_IntraRefreshBoth},
|
||||
{ MMAL_VIDEO_INTRA_REFRESH_KHRONOSEXTENSIONS, OMX_VIDEO_IntraRefreshKhronosExtensions},
|
||||
{ MMAL_VIDEO_INTRA_REFRESH_VENDORSTARTUNUSED, OMX_VIDEO_IntraRefreshVendorStartUnused},
|
||||
{ MMAL_VIDEO_INTRA_REFRESH_DUMMY, OMX_VIDEO_IntraRefreshMax},
|
||||
};
|
||||
|
||||
MMAL_VIDEO_INTRA_REFRESH_T mmalil_omx_video_intrarefresh_to_mmal(OMX_VIDEO_INTRAREFRESHTYPE omx)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; mmal_omx_video_intrarefresh_table[i].mmal != MMAL_VIDEO_INTRA_REFRESH_DUMMY; i++)
|
||||
if(mmal_omx_video_intrarefresh_table[i].omx == omx) break;
|
||||
return mmal_omx_video_intrarefresh_table[i].mmal;
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MMAL_IL_H
|
||||
#define MMAL_IL_H
|
||||
|
||||
/** \defgroup MmalILUtility MMAL to OMX IL conversion utilities
|
||||
* \ingroup MmalUtilities
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "interface/vmcs_host/khronos/IL/OMX_Core.h"
|
||||
#include "interface/vmcs_host/khronos/IL/OMX_Component.h"
|
||||
#include "interface/vmcs_host/khronos/IL/OMX_Video.h"
|
||||
#include "interface/vmcs_host/khronos/IL/OMX_Audio.h"
|
||||
#include "interface/vmcs_host/khronos/IL/OMX_Broadcom.h"
|
||||
|
||||
/** Convert MMAL status codes into OMX error codes.
|
||||
*
|
||||
* @param status MMAL status code.
|
||||
* @return OMX error code.
|
||||
*/
|
||||
OMX_ERRORTYPE mmalil_error_to_omx(MMAL_STATUS_T status);
|
||||
|
||||
/** Convert OMX error codes into MMAL status codes.
|
||||
*
|
||||
* @param error OMX error code.
|
||||
* @return MMAL status code.
|
||||
*/
|
||||
MMAL_STATUS_T mmalil_error_to_mmal(OMX_ERRORTYPE error);
|
||||
|
||||
/** Convert MMAL buffer header flags into OMX buffer header flags.
|
||||
*
|
||||
* @param flags OMX buffer header flags.
|
||||
* @return MMAL buffer header flags.
|
||||
*/
|
||||
uint32_t mmalil_buffer_flags_to_mmal(OMX_U32 flags);
|
||||
|
||||
/** Convert OMX buffer header flags into MMAL buffer header flags.
|
||||
*
|
||||
* @param flags MMAL buffer header flags.
|
||||
* @return OMX buffer header flags.
|
||||
*/
|
||||
OMX_U32 mmalil_buffer_flags_to_omx(uint32_t flags);
|
||||
|
||||
/** Convert a MMAL buffer header into an OMX buffer header.
|
||||
* Note that only the fields which have a direct mapping between OMX and MMAL are converted.
|
||||
*
|
||||
* @param omx Pointer to the destination OMX buffer header.
|
||||
* @param mmal Pointer to the source MMAL buffer header.
|
||||
*/
|
||||
void mmalil_buffer_header_to_omx(OMX_BUFFERHEADERTYPE *omx, MMAL_BUFFER_HEADER_T *mmal);
|
||||
|
||||
/** Convert an OMX buffer header into a MMAL buffer header.
|
||||
*
|
||||
* @param mmal Pointer to the destination MMAL buffer header.
|
||||
* @param omx Pointer to the source OMX buffer header.
|
||||
*/
|
||||
void mmalil_buffer_header_to_mmal(MMAL_BUFFER_HEADER_T *mmal, OMX_BUFFERHEADERTYPE *omx);
|
||||
|
||||
|
||||
OMX_PORTDOMAINTYPE mmalil_es_type_to_omx_domain(MMAL_ES_TYPE_T type);
|
||||
MMAL_ES_TYPE_T mmalil_omx_domain_to_es_type(OMX_PORTDOMAINTYPE domain);
|
||||
uint32_t mmalil_omx_audio_coding_to_encoding(OMX_AUDIO_CODINGTYPE coding);
|
||||
OMX_AUDIO_CODINGTYPE mmalil_encoding_to_omx_audio_coding(uint32_t encoding);
|
||||
uint32_t mmalil_omx_video_coding_to_encoding(OMX_VIDEO_CODINGTYPE coding);
|
||||
OMX_VIDEO_CODINGTYPE mmalil_encoding_to_omx_video_coding(uint32_t encoding);
|
||||
uint32_t mmalil_omx_image_coding_to_encoding(OMX_IMAGE_CODINGTYPE coding);
|
||||
OMX_IMAGE_CODINGTYPE mmalil_encoding_to_omx_image_coding(uint32_t encoding);
|
||||
uint32_t mmalil_omx_coding_to_encoding(uint32_t encoding, OMX_PORTDOMAINTYPE domain);
|
||||
uint32_t mmalil_omx_color_format_to_encoding(OMX_COLOR_FORMATTYPE coding);
|
||||
OMX_COLOR_FORMATTYPE mmalil_encoding_to_omx_color_format(uint32_t encoding);
|
||||
uint32_t mmalil_omx_color_space_to_mmal(OMX_COLORSPACETYPE coding);
|
||||
OMX_COLORSPACETYPE mmalil_color_space_to_omx(uint32_t coding);
|
||||
uint32_t mmalil_omx_video_profile_to_mmal(OMX_U32 level, OMX_VIDEO_CODINGTYPE coding);
|
||||
OMX_U32 mmalil_video_profile_to_omx(uint32_t profile);
|
||||
uint32_t mmalil_omx_video_level_to_mmal(OMX_U32 level, OMX_VIDEO_CODINGTYPE coding);
|
||||
OMX_U32 mmalil_video_level_to_omx(uint32_t level);
|
||||
MMAL_VIDEO_RATECONTROL_T mmalil_omx_video_ratecontrol_to_mmal(OMX_VIDEO_CONTROLRATETYPE omx);
|
||||
OMX_VIDEO_CONTROLRATETYPE mmalil_video_ratecontrol_to_omx(MMAL_VIDEO_RATECONTROL_T mmal);
|
||||
MMAL_VIDEO_INTRA_REFRESH_T mmalil_omx_video_intrarefresh_to_mmal(OMX_VIDEO_INTRAREFRESHTYPE omx);
|
||||
|
||||
/** Union of all the OMX_VIDEO/AUDIO_PARAM types */
|
||||
typedef union OMX_FORMAT_PARAM_TYPE {
|
||||
OMX_PARAM_U32TYPE common;
|
||||
|
||||
/* Video */
|
||||
OMX_VIDEO_PARAM_AVCTYPE avc;
|
||||
OMX_VIDEO_PARAM_H263TYPE h263;
|
||||
OMX_VIDEO_PARAM_MPEG2TYPE mpeg2;
|
||||
OMX_VIDEO_PARAM_MPEG4TYPE mpeg4;
|
||||
OMX_VIDEO_PARAM_WMVTYPE wmv;
|
||||
OMX_VIDEO_PARAM_RVTYPE rv;
|
||||
|
||||
/* Audio */
|
||||
OMX_AUDIO_PARAM_PCMMODETYPE pcm;
|
||||
OMX_AUDIO_PARAM_MP3TYPE mp3;
|
||||
OMX_AUDIO_PARAM_AACPROFILETYPE aac;
|
||||
OMX_AUDIO_PARAM_VORBISTYPE vorbis;
|
||||
OMX_AUDIO_PARAM_WMATYPE wma;
|
||||
OMX_AUDIO_PARAM_RATYPE ra;
|
||||
OMX_AUDIO_PARAM_SBCTYPE sbc;
|
||||
OMX_AUDIO_PARAM_ADPCMTYPE adpcm;
|
||||
OMX_AUDIO_PARAM_G723TYPE g723;
|
||||
OMX_AUDIO_PARAM_G726TYPE g726;
|
||||
OMX_AUDIO_PARAM_G729TYPE g729;
|
||||
OMX_AUDIO_PARAM_AMRTYPE amr;
|
||||
OMX_AUDIO_PARAM_GSMFRTYPE gsmfr;
|
||||
OMX_AUDIO_PARAM_GSMHRTYPE gsmhr;
|
||||
OMX_AUDIO_PARAM_GSMEFRTYPE gsmefr;
|
||||
OMX_AUDIO_PARAM_TDMAFRTYPE tdmafr;
|
||||
OMX_AUDIO_PARAM_TDMAEFRTYPE tdmaefr;
|
||||
OMX_AUDIO_PARAM_PDCFRTYPE pdcfr;
|
||||
OMX_AUDIO_PARAM_PDCEFRTYPE pdcefr;
|
||||
OMX_AUDIO_PARAM_PDCHRTYPE pdchr;
|
||||
OMX_AUDIO_PARAM_QCELP8TYPE qcelp8;
|
||||
OMX_AUDIO_PARAM_QCELP13TYPE qcelp13;
|
||||
OMX_AUDIO_PARAM_EVRCTYPE evrc;
|
||||
OMX_AUDIO_PARAM_SMVTYPE smv;
|
||||
OMX_AUDIO_PARAM_MIDITYPE midi;
|
||||
#ifdef OMX_AUDIO_CodingDDP_Supported
|
||||
OMX_AUDIO_PARAM_DDPTYPE ddp;
|
||||
#endif
|
||||
#ifdef OMX_AUDIO_CodingDTS_Supported
|
||||
OMX_AUDIO_PARAM_DTSTYPE dts;
|
||||
#endif
|
||||
|
||||
} OMX_FORMAT_PARAM_TYPE;
|
||||
|
||||
/** Get the OMX_IndexParamAudio index corresponding to a specified audio coding type.
|
||||
*
|
||||
* @param coding Audio coding type.
|
||||
* @param size Pointer used to return the size of the parameter.
|
||||
*
|
||||
* @return OMX index or 0 if no match was found.
|
||||
*/
|
||||
OMX_INDEXTYPE mmalil_omx_audio_param_index(OMX_AUDIO_CODINGTYPE coding, OMX_U32 *size);
|
||||
|
||||
/** Get the audio coding corresponding to a specified OMX_IndexParamAudio index.
|
||||
*
|
||||
* @param index Audio coding type.
|
||||
*
|
||||
* @return Audio coding type.
|
||||
*/
|
||||
OMX_AUDIO_CODINGTYPE mmalil_omx_audio_param_index_to_coding(OMX_INDEXTYPE index);
|
||||
|
||||
/** Setup a default channel mapping based on the number of channels
|
||||
* @param channel_mapping The output channel mapping
|
||||
* @param nchannels Number of channels
|
||||
*
|
||||
* @return MMAL_SUCCESS if we managed to produce a channel mapping
|
||||
*/
|
||||
MMAL_STATUS_T mmalil_omx_default_channel_mapping(OMX_AUDIO_CHANNELTYPE *channel_mapping, unsigned int nchannels);
|
||||
|
||||
/** Convert an OMX_IndexParamAudio into a MMAL elementary stream format.
|
||||
*
|
||||
* @param format Format structure to update.
|
||||
* @param coding Audio coding type.
|
||||
* @param param Source OMX_IndexParamAudio structure.
|
||||
*
|
||||
* @return The MMAL encoding if a match was found or MMAL_ENCODING_UNKNOWN otherwise.
|
||||
*/
|
||||
MMAL_FOURCC_T mmalil_omx_audio_param_to_format(MMAL_ES_FORMAT_T *format,
|
||||
OMX_AUDIO_CODINGTYPE coding, OMX_FORMAT_PARAM_TYPE *param);
|
||||
|
||||
/** Convert a MMAL elementary stream format into a OMX_IndexParamAudio structure.
|
||||
*
|
||||
* @param param OMX_IndexParamAudio structure to update.
|
||||
* @param param_index returns the OMX_IndexParamAudio index corresponding to the format.
|
||||
* @param format Source format structure.
|
||||
*
|
||||
* @return The OMX aduio coding type if a match was found or OMX_AUDIO_CodingUnused otherwise.
|
||||
*/
|
||||
OMX_AUDIO_CODINGTYPE mmalil_format_to_omx_audio_param(OMX_FORMAT_PARAM_TYPE *param,
|
||||
OMX_INDEXTYPE *param_index, MMAL_ES_FORMAT_T *format);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* MMAL_IL_H */
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "interface/vcos/vcos.h"
|
||||
#include "interface/mmal/util/mmal_list.h"
|
||||
|
||||
|
||||
/* Private list context */
|
||||
typedef struct MMAL_LIST_PRIVATE_T
|
||||
{
|
||||
MMAL_LIST_T list; /* must be first */
|
||||
VCOS_MUTEX_T lock;
|
||||
} MMAL_LIST_PRIVATE_T;
|
||||
|
||||
|
||||
/* Lock the list. */
|
||||
static inline void mmal_list_lock(MMAL_LIST_T *list)
|
||||
{
|
||||
vcos_mutex_lock(&((MMAL_LIST_PRIVATE_T*)list)->lock);
|
||||
}
|
||||
|
||||
/* Unlock the list. */
|
||||
static inline void mmal_list_unlock(MMAL_LIST_T *list)
|
||||
{
|
||||
vcos_mutex_unlock(&((MMAL_LIST_PRIVATE_T*)list)->lock);
|
||||
}
|
||||
|
||||
/* Create a new linked list. */
|
||||
MMAL_LIST_T* mmal_list_create(void)
|
||||
{
|
||||
MMAL_LIST_PRIVATE_T *private;
|
||||
|
||||
private = vcos_malloc(sizeof(MMAL_LIST_PRIVATE_T), "mmal-list");
|
||||
if (private == NULL)
|
||||
goto error;
|
||||
|
||||
if (vcos_mutex_create(&private->lock, "mmal-list lock") != VCOS_SUCCESS)
|
||||
goto error;
|
||||
|
||||
/* lock to keep coverity happy */
|
||||
vcos_mutex_lock(&private->lock);
|
||||
private->list.first = NULL;
|
||||
private->list.last = NULL;
|
||||
private->list.length = 0;
|
||||
vcos_mutex_unlock(&private->lock);
|
||||
|
||||
return &private->list;
|
||||
|
||||
error:
|
||||
vcos_free(private);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Destroy a linked list. */
|
||||
void mmal_list_destroy(MMAL_LIST_T *list)
|
||||
{
|
||||
MMAL_LIST_PRIVATE_T *private = (MMAL_LIST_PRIVATE_T*)list;
|
||||
|
||||
vcos_mutex_delete(&private->lock);
|
||||
vcos_free(private);
|
||||
}
|
||||
|
||||
/* Remove the last element in the list. */
|
||||
MMAL_LIST_ELEMENT_T* mmal_list_pop_back(MMAL_LIST_T *list)
|
||||
{
|
||||
MMAL_LIST_ELEMENT_T *element;
|
||||
|
||||
mmal_list_lock(list);
|
||||
|
||||
element = list->last;
|
||||
if (element != NULL)
|
||||
{
|
||||
list->length--;
|
||||
|
||||
list->last = element->prev;
|
||||
if (list->last)
|
||||
list->last->next = NULL;
|
||||
else
|
||||
list->first = NULL; /* list is now empty */
|
||||
|
||||
element->prev = NULL;
|
||||
element->next = NULL;
|
||||
}
|
||||
|
||||
mmal_list_unlock(list);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/* Remove the first element in the list. */
|
||||
MMAL_LIST_ELEMENT_T* mmal_list_pop_front(MMAL_LIST_T *list)
|
||||
{
|
||||
MMAL_LIST_ELEMENT_T *element;
|
||||
|
||||
mmal_list_lock(list);
|
||||
|
||||
element = list->first;
|
||||
if (element != NULL)
|
||||
{
|
||||
list->length--;
|
||||
|
||||
list->first = element->next;
|
||||
if (list->first)
|
||||
list->first->prev = NULL;
|
||||
else
|
||||
list->last = NULL; /* list is now empty */
|
||||
|
||||
element->prev = NULL;
|
||||
element->next = NULL;
|
||||
}
|
||||
|
||||
mmal_list_unlock(list);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/* Add an element to the front of the list. */
|
||||
void mmal_list_push_front(MMAL_LIST_T *list, MMAL_LIST_ELEMENT_T *element)
|
||||
{
|
||||
mmal_list_lock(list);
|
||||
|
||||
list->length++;
|
||||
|
||||
element->prev = NULL;
|
||||
element->next = list->first;
|
||||
|
||||
if (list->first)
|
||||
list->first->prev = element;
|
||||
else
|
||||
list->last = element; /* list was empty */
|
||||
|
||||
list->first = element;
|
||||
|
||||
mmal_list_unlock(list);
|
||||
}
|
||||
|
||||
/* Add an element to the back of the list. */
|
||||
void mmal_list_push_back(MMAL_LIST_T *list, MMAL_LIST_ELEMENT_T *element)
|
||||
{
|
||||
mmal_list_lock(list);
|
||||
|
||||
list->length++;
|
||||
|
||||
element->next = NULL;
|
||||
element->prev = list->last;
|
||||
|
||||
if (list->last)
|
||||
list->last->next = element;
|
||||
else
|
||||
list->first = element; /* list was empty */
|
||||
|
||||
list->last = element;
|
||||
|
||||
mmal_list_unlock(list);
|
||||
}
|
||||
|
||||
/* Insert an element into the list. */
|
||||
void mmal_list_insert(MMAL_LIST_T *list, MMAL_LIST_ELEMENT_T *element, MMAL_LIST_COMPARE_T compare)
|
||||
{
|
||||
MMAL_LIST_ELEMENT_T *cur;
|
||||
|
||||
mmal_list_lock(list);
|
||||
|
||||
if (list->first == NULL)
|
||||
{
|
||||
/* List empty */
|
||||
mmal_list_unlock(list);
|
||||
mmal_list_push_front(list, element);
|
||||
return;
|
||||
}
|
||||
|
||||
cur = list->first;
|
||||
while (cur)
|
||||
{
|
||||
if (compare(element, cur))
|
||||
{
|
||||
/* Slot found! */
|
||||
list->length++;
|
||||
if (cur == list->first)
|
||||
list->first = element;
|
||||
else
|
||||
cur->prev->next = element;
|
||||
element->prev = cur->prev;
|
||||
element->next = cur;
|
||||
cur->prev = element;
|
||||
mmal_list_unlock(list);
|
||||
return;
|
||||
}
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
/* If we get here, none of the existing elements are greater
|
||||
* than the new on, so just add it to the back of the list */
|
||||
mmal_list_unlock(list);
|
||||
mmal_list_push_back(list, element);
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MMAL_LIST_H
|
||||
#define MMAL_LIST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup MmalList Generic Linked List
|
||||
* This provides a thread-safe implementation of a linked list which can be used
|
||||
* with any data type. */
|
||||
/* @{ */
|
||||
|
||||
/** Single element in the list */
|
||||
typedef struct MMAL_LIST_ELEMENT_T
|
||||
{
|
||||
struct MMAL_LIST_ELEMENT_T *next;
|
||||
struct MMAL_LIST_ELEMENT_T *prev;
|
||||
} MMAL_LIST_ELEMENT_T;
|
||||
|
||||
/** Linked list type.
|
||||
* Clients shouldn't modify this directly. Use the provided API functions to
|
||||
* add new elements. The public members are only for debug purposes.
|
||||
* */
|
||||
typedef struct MMAL_LIST_T
|
||||
{
|
||||
unsigned int length; /**< Number of elements in the list (read-only) */
|
||||
MMAL_LIST_ELEMENT_T *first; /**< First element in the list (read-only) */
|
||||
MMAL_LIST_ELEMENT_T *last; /**< Last element in the list (read-only) */
|
||||
} MMAL_LIST_T;
|
||||
|
||||
/** Create a new linked list.
|
||||
*
|
||||
* @return Pointer to new queue (NULL on failure).
|
||||
*/
|
||||
MMAL_LIST_T* mmal_list_create(void);
|
||||
|
||||
/** Destroy a linked list.
|
||||
*
|
||||
* @param list List to destroy
|
||||
*/
|
||||
void mmal_list_destroy(MMAL_LIST_T *list);
|
||||
|
||||
/** Remove the last element in the list.
|
||||
*
|
||||
* @param list List to remove from
|
||||
*
|
||||
* @return Pointer to the last element (or NULL if empty)
|
||||
*/
|
||||
MMAL_LIST_ELEMENT_T* mmal_list_pop_back(MMAL_LIST_T *list);
|
||||
|
||||
/** Remove the first element in the list.
|
||||
*
|
||||
* @param list List to remove from
|
||||
*
|
||||
* @return Pointer to the first element (or NULL if empty)
|
||||
*/
|
||||
MMAL_LIST_ELEMENT_T* mmal_list_pop_front(MMAL_LIST_T *list);
|
||||
|
||||
/** Add an element to the front of the list.
|
||||
*
|
||||
* @param list List to add to
|
||||
* @param element The element to add
|
||||
*/
|
||||
void mmal_list_push_front(MMAL_LIST_T *list, MMAL_LIST_ELEMENT_T *element);
|
||||
|
||||
/** Add an element to the back of the list.
|
||||
*
|
||||
* @param list List to add to
|
||||
* @param element The element to add
|
||||
*/
|
||||
void mmal_list_push_back(MMAL_LIST_T *list, MMAL_LIST_ELEMENT_T *element);
|
||||
|
||||
/** List comparison function.
|
||||
* This is supplied by a client when inserting an element in
|
||||
* the middle of the list. The list will always insert a smaller
|
||||
* element in front of a larger element.
|
||||
*
|
||||
* @return TRUE: lhs < rhs
|
||||
* FALSE: lhs >= rhs
|
||||
*/
|
||||
typedef int (*MMAL_LIST_COMPARE_T)(MMAL_LIST_ELEMENT_T *lhs, MMAL_LIST_ELEMENT_T *rhs);
|
||||
|
||||
/** Insert an element into the list.
|
||||
* The location where the element is inserted is determined using
|
||||
* the supplied comparison function. Smaller elements are inserted
|
||||
* in front of larger elements.
|
||||
*
|
||||
* @param list List to add to
|
||||
* @param element The element to insert
|
||||
* @param compare Comparison function supplied by the client
|
||||
*/
|
||||
void mmal_list_insert(MMAL_LIST_T *list, MMAL_LIST_ELEMENT_T *element, MMAL_LIST_COMPARE_T compare);
|
||||
|
||||
/* @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MMAL_LIST_H */
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "mmal_param_convert.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct string_pair_t
|
||||
{
|
||||
const char *string;
|
||||
int value;
|
||||
} string_pair_t;
|
||||
|
||||
static MMAL_STATUS_T parse_enum(int *dest, string_pair_t *pairs, size_t n_pairs, const char *str)
|
||||
{
|
||||
size_t i;
|
||||
for (i=0; i<n_pairs; i++)
|
||||
{
|
||||
if (vcos_strcasecmp(str, pairs[i].string) == 0)
|
||||
{
|
||||
*dest = pairs[i].value;
|
||||
return MMAL_SUCCESS;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return MMAL_EINVAL;
|
||||
}
|
||||
|
||||
MMAL_STATUS_T mmal_parse_video_size(uint32_t *w, uint32_t *h, const char *str)
|
||||
{
|
||||
static struct {
|
||||
const char *name;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} sizes[] = {
|
||||
{ "1080p", 1920, 1080 },
|
||||
{ "720p", 1280, 720 },
|
||||
{ "vga", 640, 480 },
|
||||
{ "wvga", 800, 480 },
|
||||
{ "cif", 352, 288 },
|
||||
{ "qcif", 352/2, 288/2 },
|
||||
};
|
||||
size_t i;
|
||||
for (i=0; i<vcos_countof(sizes); i++)
|
||||
{
|
||||
if (vcos_strcasecmp(str, sizes[i].name) == 0)
|
||||
{
|
||||
*w = sizes[i].width;
|
||||
*h = sizes[i].height;
|
||||
return MMAL_SUCCESS;
|
||||
}
|
||||
}
|
||||
return MMAL_EINVAL;
|
||||
}
|
||||
|
||||
MMAL_STATUS_T mmal_parse_rational(MMAL_RATIONAL_T *dest, const char *str)
|
||||
{
|
||||
MMAL_STATUS_T ret;
|
||||
char *endptr;
|
||||
long num, den = 1;
|
||||
num = strtoul(str, &endptr, 0);
|
||||
if (endptr[0] == '\0')
|
||||
{
|
||||
/* that's it */
|
||||
ret = MMAL_SUCCESS;
|
||||
}
|
||||
else if (endptr[0] == '/')
|
||||
{
|
||||
den = strtoul(endptr+1, &endptr, 0);
|
||||
if (endptr[0] == '\0')
|
||||
ret = MMAL_SUCCESS;
|
||||
else
|
||||
ret = MMAL_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = MMAL_EINVAL;
|
||||
}
|
||||
dest->num = num;
|
||||
dest->den = den;
|
||||
return ret;
|
||||
}
|
||||
|
||||
MMAL_STATUS_T mmal_parse_int(int *dest, const char *str)
|
||||
{
|
||||
char *endptr;
|
||||
long i = strtol(str, &endptr, 0);
|
||||
if (endptr[0] == '\0')
|
||||
{
|
||||
*dest = i;
|
||||
return MMAL_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MMAL_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
MMAL_STATUS_T mmal_parse_uint(unsigned int *dest, const char *str)
|
||||
{
|
||||
char *endptr;
|
||||
unsigned long i = strtoul(str, &endptr, 0);
|
||||
if (endptr[0] == '\0')
|
||||
{
|
||||
*dest = i;
|
||||
return MMAL_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MMAL_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
MMAL_STATUS_T mmal_parse_video_codec(uint32_t *dest, const char *str)
|
||||
{
|
||||
static string_pair_t video_codec_enums[] = {
|
||||
{ "h264", MMAL_ENCODING_H264 },
|
||||
{ "h263", MMAL_ENCODING_H263 },
|
||||
{ "mpeg4", MMAL_ENCODING_MP4V },
|
||||
{ "mpeg2", MMAL_ENCODING_MP2V },
|
||||
{ "vp8", MMAL_ENCODING_VP8 },
|
||||
{ "vp7", MMAL_ENCODING_VP7 },
|
||||
{ "vp6", MMAL_ENCODING_VP6 },
|
||||
};
|
||||
int i = 0;
|
||||
MMAL_STATUS_T ret;
|
||||
|
||||
ret = parse_enum(&i, video_codec_enums, vcos_countof(video_codec_enums), str);
|
||||
*dest = i;
|
||||
return ret;
|
||||
}
|
||||
|
||||
MMAL_STATUS_T mmal_parse_geometry(MMAL_RECT_T *dest, const char *str)
|
||||
{
|
||||
MMAL_STATUS_T ret;
|
||||
uint32_t w, h, x, y;
|
||||
x = y = w = h = 0;
|
||||
/* coverity[secure_coding] */
|
||||
if (sscanf(str, "%d*%d+%d+%d", &w,&h,&x,&y) == 4 ||
|
||||
sscanf(str, "%d*%d", &w,&h) == 2)
|
||||
{
|
||||
dest->x = x;
|
||||
dest->y = y;
|
||||
dest->width = w;
|
||||
dest->height = h;
|
||||
ret = MMAL_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = MMAL_EINVAL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Support for setting/getting parameters as string values.
|
||||
*/
|
||||
|
||||
#ifndef MMAL_PARAM_CONVERT_H
|
||||
#define MMAL_PARAM_CONVERT_H
|
||||
|
||||
#include "interface/mmal/mmal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Parse a video size. e.g. "1080p" gives 1920x1080.
|
||||
*
|
||||
* @param w width result
|
||||
* @param h height result
|
||||
* @param str string to convert
|
||||
* @return MMAL_SUCCESS or error code
|
||||
*/
|
||||
MMAL_STATUS_T mmal_parse_video_size(uint32_t *w, uint32_t *h, const char *str);
|
||||
|
||||
/** Parse a rational number. e.g. "30000/1001", "30", etc.
|
||||
* @param dest filled in with result
|
||||
* @param str string to convert
|
||||
* @return MMAL_SUCCESS or error code
|
||||
*/
|
||||
MMAL_STATUS_T mmal_parse_rational(MMAL_RATIONAL_T *dest, const char *str);
|
||||
|
||||
/** Parse an integer, e.g. -10, 0x1A, etc.
|
||||
* @param dest filled in with result
|
||||
* @param str string to convert
|
||||
* @return MMAL_SUCCESS or error code
|
||||
*/
|
||||
MMAL_STATUS_T mmal_parse_int(int *dest, const char *str);
|
||||
|
||||
/** Parse an unsigned integer, e.g. 10, 0x1A, etc.
|
||||
* @param dest filled in with result
|
||||
* @param str string to convert
|
||||
* @return MMAL_SUCCESS or error code
|
||||
*/
|
||||
MMAL_STATUS_T mmal_parse_uint(unsigned int *dest, const char *str);
|
||||
|
||||
/** Parse a geometry for a rectangle
|
||||
*
|
||||
* e.g. 100*100+50+75
|
||||
* or 200*150
|
||||
* @param dest filled in with result
|
||||
* @param str string to convert
|
||||
* @return MMAL_SUCCESS or error code
|
||||
*/
|
||||
MMAL_STATUS_T mmal_parse_geometry(MMAL_RECT_T *dest, const char *str);
|
||||
|
||||
/** Parse a video codec name (something that can be encoded/decoded)
|
||||
* @param str string to convert
|
||||
* @param dest filled in with result
|
||||
* @return MMAL_SUCCESS or error code
|
||||
*/
|
||||
MMAL_STATUS_T mmal_parse_video_codec(uint32_t *dest, const char *str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "interface/mmal/mmal.h"
|
||||
#include "mmal_encodings.h"
|
||||
#include "mmal_util.h"
|
||||
#include "mmal_logging.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define STATUS_TO_STR(x) { MMAL_##x, #x }
|
||||
|
||||
static struct {
|
||||
MMAL_STATUS_T status;
|
||||
const char *str;
|
||||
} status_to_string_map[] =
|
||||
{
|
||||
STATUS_TO_STR(SUCCESS),
|
||||
STATUS_TO_STR(ENOMEM),
|
||||
STATUS_TO_STR(ENOSPC),
|
||||
STATUS_TO_STR(EINVAL),
|
||||
STATUS_TO_STR(ENOSYS),
|
||||
STATUS_TO_STR(ENOENT),
|
||||
STATUS_TO_STR(ENXIO),
|
||||
STATUS_TO_STR(EIO),
|
||||
STATUS_TO_STR(ESPIPE),
|
||||
STATUS_TO_STR(ECORRUPT),
|
||||
STATUS_TO_STR(ENOTREADY),
|
||||
STATUS_TO_STR(ECONFIG),
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
const char *mmal_status_to_string(MMAL_STATUS_T status)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i=0; status_to_string_map[i].str; i++)
|
||||
if (status_to_string_map[i].status == status)
|
||||
break;
|
||||
|
||||
return status_to_string_map[i].str ? status_to_string_map[i].str : "UNKNOWN";
|
||||
}
|
||||
|
||||
static struct {
|
||||
uint32_t encoding;
|
||||
uint32_t pitch_num;
|
||||
uint32_t pitch_den;
|
||||
} pixel_pitch[] =
|
||||
{
|
||||
{MMAL_ENCODING_I420, 1, 1},
|
||||
{MMAL_ENCODING_YV12, 1, 1},
|
||||
{MMAL_ENCODING_I422, 1, 1},
|
||||
{MMAL_ENCODING_NV21, 1, 1},
|
||||
{MMAL_ENCODING_NV12, 1, 1},
|
||||
{MMAL_ENCODING_ARGB, 4, 1},
|
||||
{MMAL_ENCODING_RGBA, 4, 1},
|
||||
{MMAL_ENCODING_RGB32, 4, 1},
|
||||
{MMAL_ENCODING_ABGR, 4, 1},
|
||||
{MMAL_ENCODING_BGRA, 4, 1},
|
||||
{MMAL_ENCODING_BGR32, 4, 1},
|
||||
{MMAL_ENCODING_RGB16, 2, 1},
|
||||
{MMAL_ENCODING_RGB24, 3, 1},
|
||||
{MMAL_ENCODING_BGR16, 2, 1},
|
||||
{MMAL_ENCODING_BGR24, 3, 1},
|
||||
|
||||
{MMAL_ENCODING_YUYV, 2, 1},
|
||||
{MMAL_ENCODING_YVYU, 2, 1},
|
||||
{MMAL_ENCODING_UYVY, 2, 1},
|
||||
{MMAL_ENCODING_VYUY, 2, 1},
|
||||
/* {MMAL_ENCODING_YUVUV128, 1, 1}, That's a special case which must not be included */
|
||||
{MMAL_ENCODING_UNKNOWN, 0, 0}
|
||||
};
|
||||
|
||||
uint32_t mmal_encoding_stride_to_width(uint32_t encoding, uint32_t stride)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for(i = 0; pixel_pitch[i].encoding != MMAL_ENCODING_UNKNOWN; i++)
|
||||
if(pixel_pitch[i].encoding == encoding) break;
|
||||
|
||||
if(pixel_pitch[i].encoding == MMAL_ENCODING_UNKNOWN)
|
||||
return 0;
|
||||
|
||||
return pixel_pitch[i].pitch_den * stride / pixel_pitch[i].pitch_num;
|
||||
}
|
||||
|
||||
uint32_t mmal_encoding_width_to_stride(uint32_t encoding, uint32_t width)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for(i = 0; pixel_pitch[i].encoding != MMAL_ENCODING_UNKNOWN; i++)
|
||||
if(pixel_pitch[i].encoding == encoding) break;
|
||||
|
||||
if(pixel_pitch[i].encoding == MMAL_ENCODING_UNKNOWN)
|
||||
return 0;
|
||||
|
||||
return pixel_pitch[i].pitch_num * width / pixel_pitch[i].pitch_den;
|
||||
}
|
||||
|
||||
const char* mmal_port_type_to_string(MMAL_PORT_TYPE_T type)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MMAL_PORT_TYPE_INPUT: str = "in"; break;
|
||||
case MMAL_PORT_TYPE_OUTPUT: str = "out"; break;
|
||||
case MMAL_PORT_TYPE_CLOCK: str = "clk"; break;
|
||||
case MMAL_PORT_TYPE_CONTROL: str = "ctr"; break;
|
||||
default: str = "invalid"; break;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
MMAL_PARAMETER_HEADER_T *mmal_port_parameter_alloc_get(MMAL_PORT_T *port,
|
||||
uint32_t id, uint32_t size, MMAL_STATUS_T *p_status)
|
||||
{
|
||||
MMAL_PARAMETER_HEADER_T *param = NULL;
|
||||
MMAL_STATUS_T status = MMAL_ENOSYS;
|
||||
|
||||
if (size < sizeof(MMAL_PARAMETER_HEADER_T))
|
||||
size = sizeof(MMAL_PARAMETER_HEADER_T);
|
||||
|
||||
if ((param = vcos_calloc(1, size, "mmal_port_param_get")) == NULL)
|
||||
{
|
||||
status = MMAL_ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
param->id = id;
|
||||
param->size = size;
|
||||
|
||||
if ((status = mmal_port_parameter_get(port, param)) == MMAL_ENOSPC)
|
||||
{
|
||||
/* We need to reallocate to get enough space for all parameter data */
|
||||
size = param->size;
|
||||
vcos_free(param);
|
||||
if ((param = vcos_calloc(1, size, "mmal_port_param_get")) == NULL)
|
||||
{
|
||||
status = MMAL_ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Now retrieve it again */
|
||||
param->id = id;
|
||||
param->size = size;
|
||||
status = mmal_port_parameter_get(port, param);
|
||||
}
|
||||
|
||||
if (status != MMAL_SUCCESS)
|
||||
goto error;
|
||||
|
||||
end:
|
||||
if (p_status) *p_status = status;
|
||||
return param;
|
||||
error:
|
||||
if (param) vcos_free(param);
|
||||
param = NULL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
void mmal_port_parameter_free(MMAL_PARAMETER_HEADER_T *param)
|
||||
{
|
||||
vcos_free(param);
|
||||
}
|
||||
|
||||
/** Copy buffer header metadata from source to dest
|
||||
*/
|
||||
void mmal_buffer_header_copy_header(MMAL_BUFFER_HEADER_T *dest, const MMAL_BUFFER_HEADER_T *src)
|
||||
{
|
||||
dest->cmd = src->cmd;
|
||||
dest->offset = src->offset;
|
||||
dest->length = src->length;
|
||||
dest->flags = src->flags;
|
||||
dest->pts = src->pts;
|
||||
dest->dts = src->dts;
|
||||
*dest->type = *src->type;
|
||||
}
|
||||
|
||||
/** Create a pool of MMAL_BUFFER_HEADER_T */
|
||||
MMAL_POOL_T *mmal_port_pool_create(MMAL_PORT_T *port, unsigned int headers, uint32_t payload_size)
|
||||
{
|
||||
if (!port || !port->priv)
|
||||
return NULL;
|
||||
|
||||
LOG_TRACE("%s(%i:%i) port %p, headers %u, size %i", port->component->name,
|
||||
(int)port->type, (int)port->index, port, headers, (int)payload_size);
|
||||
|
||||
/* Create a pool and ask the port for some memory */
|
||||
return mmal_pool_create_with_allocator(headers, payload_size, (void *)port,
|
||||
(mmal_pool_allocator_alloc_t)mmal_port_payload_alloc,
|
||||
(mmal_pool_allocator_free_t)mmal_port_payload_free);
|
||||
}
|
||||
|
||||
/** Destroy a pool of MMAL_BUFFER_HEADER_T */
|
||||
void mmal_port_pool_destroy(MMAL_PORT_T *port, MMAL_POOL_T *pool)
|
||||
{
|
||||
if (!port || !port->priv || !pool)
|
||||
return;
|
||||
|
||||
LOG_TRACE("%s(%i:%i) port %p, pool %p", port->component->name,
|
||||
(int)port->type, (int)port->index, port, pool);
|
||||
|
||||
if (!vcos_verify(!port->is_enabled))
|
||||
{
|
||||
LOG_ERROR("port %p, pool %p destroyed while port enabled", port, pool);
|
||||
mmal_port_disable(port);
|
||||
}
|
||||
|
||||
mmal_pool_destroy(pool);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void mmal_log_dump_port(MMAL_PORT_T *port)
|
||||
{
|
||||
if (!port)
|
||||
return;
|
||||
|
||||
LOG_DEBUG("%s(%p)", port->name, port);
|
||||
|
||||
mmal_log_dump_format(port->format);
|
||||
|
||||
LOG_DEBUG(" buffers num: %i(opt %i, min %i), size: %i(opt %i, min: %i), align: %i",
|
||||
port->buffer_num, port->buffer_num_recommended, port->buffer_num_min,
|
||||
port->buffer_size, port->buffer_size_recommended, port->buffer_size_min,
|
||||
port->buffer_alignment_min);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void mmal_log_dump_format(MMAL_ES_FORMAT_T *format)
|
||||
{
|
||||
const char *name_type;
|
||||
|
||||
if (!format)
|
||||
return;
|
||||
|
||||
switch(format->type)
|
||||
{
|
||||
case MMAL_ES_TYPE_AUDIO: name_type = "audio"; break;
|
||||
case MMAL_ES_TYPE_VIDEO: name_type = "video"; break;
|
||||
case MMAL_ES_TYPE_SUBPICTURE: name_type = "subpicture"; break;
|
||||
default: name_type = "unknown"; break;
|
||||
}
|
||||
|
||||
LOG_DEBUG("type: %s, fourcc: %4.4s", name_type, (char *)&format->encoding);
|
||||
LOG_DEBUG(" bitrate: %i, framed: %i", format->bitrate,
|
||||
!!(format->flags & MMAL_ES_FORMAT_FLAG_FRAMED));
|
||||
LOG_DEBUG(" extra data: %i, %p", format->extradata_size, format->extradata);
|
||||
switch(format->type)
|
||||
{
|
||||
case MMAL_ES_TYPE_AUDIO:
|
||||
LOG_DEBUG(" samplerate: %i, channels: %i, bps: %i, block align: %i",
|
||||
format->es->audio.sample_rate, format->es->audio.channels,
|
||||
format->es->audio.bits_per_sample, format->es->audio.block_align);
|
||||
break;
|
||||
|
||||
case MMAL_ES_TYPE_VIDEO:
|
||||
LOG_DEBUG(" width: %i, height: %i, (%i,%i,%i,%i)",
|
||||
format->es->video.width, format->es->video.height,
|
||||
format->es->video.crop.x, format->es->video.crop.y,
|
||||
format->es->video.crop.width, format->es->video.crop.height);
|
||||
LOG_DEBUG(" pixel aspect ratio: %i/%i, frame rate: %i/%i",
|
||||
format->es->video.par.num, format->es->video.par.den,
|
||||
format->es->video.frame_rate.num, format->es->video.frame_rate.den);
|
||||
break;
|
||||
|
||||
case MMAL_ES_TYPE_SUBPICTURE:
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
MMAL_PORT_T *mmal_util_get_port(MMAL_COMPONENT_T *comp, MMAL_PORT_TYPE_T type, unsigned index)
|
||||
{
|
||||
unsigned num;
|
||||
MMAL_PORT_T **list;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MMAL_PORT_TYPE_INPUT:
|
||||
num = comp->input_num;
|
||||
list = comp->input;
|
||||
break;
|
||||
|
||||
case MMAL_PORT_TYPE_OUTPUT:
|
||||
num = comp->output_num;
|
||||
list = comp->output;
|
||||
break;
|
||||
|
||||
case MMAL_PORT_TYPE_CLOCK:
|
||||
num = comp->clock_num;
|
||||
list = comp->clock;
|
||||
break;
|
||||
|
||||
case MMAL_PORT_TYPE_CONTROL:
|
||||
num = 1;
|
||||
list = &comp->control;
|
||||
break;
|
||||
|
||||
default:
|
||||
vcos_assert(0);
|
||||
return NULL;
|
||||
}
|
||||
if (index < num)
|
||||
/* coverity[ptr_arith] num is 1 here */
|
||||
return list[index];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *mmal_4cc_to_string(char *buf, size_t len, uint32_t fourcc)
|
||||
{
|
||||
char *src = (char*)&fourcc;
|
||||
vcos_assert(len >= 5);
|
||||
if (len < 5)
|
||||
{
|
||||
buf[0] = '\0';
|
||||
}
|
||||
else if (fourcc)
|
||||
{
|
||||
memcpy(buf, src, 4);
|
||||
buf[4] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(buf, len, "<0>");
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MMAL_UTIL_H
|
||||
#define MMAL_UTIL_H
|
||||
|
||||
#include "mmal.h"
|
||||
|
||||
/** \defgroup MmalUtilities Utility functions
|
||||
* The utility functions provide helpers for common functionality that is not part
|
||||
* of the core MMAL API.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Offset in bytes of FIELD in TYPE. */
|
||||
#define MMAL_OFFSET(TYPE, FIELD) ((size_t)((uint8_t *)&((TYPE*)0)->FIELD - (uint8_t *)0))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Convert a status to a statically-allocated string.
|
||||
*
|
||||
* @param status The MMAL status code.
|
||||
* @return A C string describing the status code.
|
||||
*/
|
||||
const char *mmal_status_to_string(MMAL_STATUS_T status);
|
||||
|
||||
/** Convert stride to pixel width for a given pixel encoding.
|
||||
*
|
||||
* @param encoding The pixel encoding (such as one of the \ref MmalEncodings "pre-defined encodings")
|
||||
* @param stride The stride in bytes.
|
||||
* @return The width in pixels.
|
||||
*/
|
||||
uint32_t mmal_encoding_stride_to_width(uint32_t encoding, uint32_t stride);
|
||||
|
||||
/** Convert pixel width to stride for a given pixel encoding
|
||||
*
|
||||
* @param encoding The pixel encoding (such as one of the \ref MmalEncodings "pre-defined encodings")
|
||||
* @param width The width in pixels.
|
||||
* @return The stride in bytes.
|
||||
*/
|
||||
uint32_t mmal_encoding_width_to_stride(uint32_t encoding, uint32_t width);
|
||||
|
||||
/** Convert a port type to a string.
|
||||
*
|
||||
* @param type The MMAL port type.
|
||||
* @return A NULL-terminated string describing the port type.
|
||||
*/
|
||||
const char* mmal_port_type_to_string(MMAL_PORT_TYPE_T type);
|
||||
|
||||
/** Get a parameter from a port allocating the required amount of memory
|
||||
* for the parameter (i.e. for variable length parameters like URI or arrays).
|
||||
* The size field will be set on output to the actual size of the
|
||||
* parameter allocated and retrieved.
|
||||
*
|
||||
* The pointer returned must be released by a call to \ref mmal_port_parameter_free().
|
||||
*
|
||||
* @param port port to send request to
|
||||
* @param id parameter id
|
||||
* @param size initial size hint for allocation (can be 0)
|
||||
* @param status status of the parameter get operation (can be 0)
|
||||
* @return pointer to the header of the parameter or NULL on failure.
|
||||
*/
|
||||
MMAL_PARAMETER_HEADER_T *mmal_port_parameter_alloc_get(MMAL_PORT_T *port,
|
||||
uint32_t id, uint32_t size, MMAL_STATUS_T *status);
|
||||
|
||||
/** Free a parameter structure previously allocated via
|
||||
* \ref mmal_port_parameter_alloc_get().
|
||||
*
|
||||
* @param param pointer to header of the parameter
|
||||
*/
|
||||
void mmal_port_parameter_free(MMAL_PARAMETER_HEADER_T *param);
|
||||
|
||||
/** Copy buffer header metadata from source to destination.
|
||||
*
|
||||
* @param dest The destination buffer header.
|
||||
* @param src The source buffer header.
|
||||
*/
|
||||
void mmal_buffer_header_copy_header(MMAL_BUFFER_HEADER_T *dest, const MMAL_BUFFER_HEADER_T *src);
|
||||
|
||||
/** Create a pool of MMAL_BUFFER_HEADER_T associated with a specific port.
|
||||
* This allows a client to allocate memory for the payload buffers based on the preferences
|
||||
* of a port. This for instance will allow the port to allocate memory which can be shared
|
||||
* between the host processor and videocore.
|
||||
* After allocation, all allocated buffer headers will have been added to the queue.
|
||||
*
|
||||
* It is valid to create a pool with no buffer headers, or with zero size payload buffers.
|
||||
* The mmal_pool_resize() function can be used to increase or decrease the number of buffer
|
||||
* headers, or the size of the payload buffers, after creation of the pool.
|
||||
*
|
||||
* @param port Port responsible for creating the pool.
|
||||
* @param headers Number of buffers which will be allocated with the pool.
|
||||
* @param payload_size Size of the payload buffer which will be allocated in
|
||||
* each of the buffer headers.
|
||||
* @return Pointer to the newly created pool or NULL on failure.
|
||||
*/
|
||||
MMAL_POOL_T *mmal_port_pool_create(MMAL_PORT_T *port,
|
||||
unsigned int headers, uint32_t payload_size);
|
||||
|
||||
/** Destroy a pool of MMAL_BUFFER_HEADER_T associated with a specific port.
|
||||
* This will also deallocate all of the memory which was allocated when creating or
|
||||
* resizing the pool.
|
||||
*
|
||||
* @param port Pointer to the port responsible for creating the pool.
|
||||
* @param pool Pointer to the pool to be destroyed.
|
||||
*/
|
||||
void mmal_port_pool_destroy(MMAL_PORT_T *port, MMAL_POOL_T *pool);
|
||||
|
||||
/** Log the content of a \ref MMAL_PORT_T structure.
|
||||
*
|
||||
* @param port Pointer to the port to dump.
|
||||
*/
|
||||
void mmal_log_dump_port(MMAL_PORT_T *port);
|
||||
|
||||
/** Log the content of a \ref MMAL_ES_FORMAT_T structure.
|
||||
*
|
||||
* @param format Pointer to the format to dump.
|
||||
*/
|
||||
void mmal_log_dump_format(MMAL_ES_FORMAT_T *format);
|
||||
|
||||
/** Return the nth port.
|
||||
*
|
||||
* @param comp component to query
|
||||
* @param index port index
|
||||
* @param type port type
|
||||
*
|
||||
* @return port or NULL if not found
|
||||
*/
|
||||
MMAL_PORT_T *mmal_util_get_port(MMAL_COMPONENT_T *comp, MMAL_PORT_TYPE_T type, unsigned index);
|
||||
|
||||
/** Convert a 4cc into a string.
|
||||
*
|
||||
* @param buf Destination for result
|
||||
* @param len Size of result buffer
|
||||
* @param fourcc 4cc to be converted
|
||||
* @return converted string (buf)
|
||||
*
|
||||
*/
|
||||
char *mmal_4cc_to_string(char *buf, size_t len, uint32_t fourcc);
|
||||
|
||||
|
||||
/** On FW prior to June 2016, camera and video_splitter
|
||||
* had BGR24 and RGB24 support reversed.
|
||||
* This is now fixed, and this function will return whether the
|
||||
* FW has the fix or not.
|
||||
*
|
||||
* @param port MMAL port to check (on camera or video_splitter)
|
||||
* @return 0 if old firmware, 1 if new.
|
||||
*
|
||||
*/
|
||||
int mmal_util_rgb_order_fixed(MMAL_PORT_T *port);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "mmal_util_params.h"
|
||||
|
||||
/** Helper function to set the value of a boolean parameter */
|
||||
MMAL_STATUS_T mmal_port_parameter_set_boolean(MMAL_PORT_T *port, uint32_t id, MMAL_BOOL_T value)
|
||||
{
|
||||
MMAL_PARAMETER_BOOLEAN_T param = {{id, sizeof(param)}, value};
|
||||
return mmal_port_parameter_set(port, ¶m.hdr);
|
||||
}
|
||||
|
||||
/** Helper function to get the value of a boolean parameter */
|
||||
MMAL_STATUS_T mmal_port_parameter_get_boolean(MMAL_PORT_T *port, uint32_t id, MMAL_BOOL_T *value)
|
||||
{
|
||||
MMAL_PARAMETER_BOOLEAN_T param = {{id, sizeof(param)}, 0};
|
||||
// coverity[overrun-buffer-val] Structure accessed correctly via size field
|
||||
MMAL_STATUS_T status = mmal_port_parameter_get(port, ¶m.hdr);
|
||||
if (status == MMAL_SUCCESS)
|
||||
*value = param.enable;
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Helper function to set the value of a 64 bits unsigned integer parameter */
|
||||
MMAL_STATUS_T mmal_port_parameter_set_uint64(MMAL_PORT_T *port, uint32_t id, uint64_t value)
|
||||
{
|
||||
MMAL_PARAMETER_UINT64_T param = {{id, sizeof(param)}, value};
|
||||
return mmal_port_parameter_set(port, ¶m.hdr);
|
||||
}
|
||||
|
||||
/** Helper function to get the value of a 64 bits unsigned integer parameter */
|
||||
MMAL_STATUS_T mmal_port_parameter_get_uint64(MMAL_PORT_T *port, uint32_t id, uint64_t *value)
|
||||
{
|
||||
MMAL_PARAMETER_UINT64_T param = {{id, sizeof(param)}, 0LL};
|
||||
// coverity[overrun-buffer-val] Structure accessed correctly via size field
|
||||
MMAL_STATUS_T status = mmal_port_parameter_get(port, ¶m.hdr);
|
||||
if (status == MMAL_SUCCESS)
|
||||
*value = param.value;
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Helper function to set the value of a 64 bits signed integer parameter */
|
||||
MMAL_STATUS_T mmal_port_parameter_set_int64(MMAL_PORT_T *port, uint32_t id, int64_t value)
|
||||
{
|
||||
MMAL_PARAMETER_INT64_T param = {{id, sizeof(param)}, value};
|
||||
return mmal_port_parameter_set(port, ¶m.hdr);
|
||||
}
|
||||
|
||||
/** Helper function to get the value of a 64 bits signed integer parameter */
|
||||
MMAL_STATUS_T mmal_port_parameter_get_int64(MMAL_PORT_T *port, uint32_t id, int64_t *value)
|
||||
{
|
||||
MMAL_PARAMETER_INT64_T param = {{id, sizeof(param)}, 0LL};
|
||||
// coverity[overrun-buffer-val] Structure accessed correctly via size field
|
||||
MMAL_STATUS_T status = mmal_port_parameter_get(port, ¶m.hdr);
|
||||
if (status == MMAL_SUCCESS)
|
||||
*value = param.value;
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Helper function to set the value of a 32 bits unsigned integer parameter */
|
||||
MMAL_STATUS_T mmal_port_parameter_set_uint32(MMAL_PORT_T *port, uint32_t id, uint32_t value)
|
||||
{
|
||||
MMAL_PARAMETER_UINT32_T param = {{id, sizeof(param)}, value};
|
||||
return mmal_port_parameter_set(port, ¶m.hdr);
|
||||
}
|
||||
|
||||
/** Helper function to get the value of a 32 bits unsigned integer parameter */
|
||||
MMAL_STATUS_T mmal_port_parameter_get_uint32(MMAL_PORT_T *port, uint32_t id, uint32_t *value)
|
||||
{
|
||||
MMAL_PARAMETER_UINT32_T param = {{id, sizeof(param)}, 0};
|
||||
// coverity[overrun-buffer-val] Structure accessed correctly via size field
|
||||
MMAL_STATUS_T status = mmal_port_parameter_get(port, ¶m.hdr);
|
||||
if (status == MMAL_SUCCESS)
|
||||
*value = param.value;
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Helper function to set the value of a 32 bits signed integer parameter */
|
||||
MMAL_STATUS_T mmal_port_parameter_set_int32(MMAL_PORT_T *port, uint32_t id, int32_t value)
|
||||
{
|
||||
MMAL_PARAMETER_INT32_T param = {{id, sizeof(param)}, value};
|
||||
return mmal_port_parameter_set(port, ¶m.hdr);
|
||||
}
|
||||
|
||||
/** Helper function to get the value of a 32 bits signed integer parameter */
|
||||
MMAL_STATUS_T mmal_port_parameter_get_int32(MMAL_PORT_T *port, uint32_t id, int32_t *value)
|
||||
{
|
||||
MMAL_PARAMETER_INT32_T param = {{id, sizeof(param)}, 0};
|
||||
// coverity[overrun-buffer-val] Structure accessed correctly via size field
|
||||
MMAL_STATUS_T status = mmal_port_parameter_get(port, ¶m.hdr);
|
||||
if (status == MMAL_SUCCESS)
|
||||
*value = param.value;
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Helper function to set the value of a rational parameter */
|
||||
MMAL_STATUS_T mmal_port_parameter_set_rational(MMAL_PORT_T *port, uint32_t id, MMAL_RATIONAL_T value)
|
||||
{
|
||||
MMAL_PARAMETER_RATIONAL_T param = {{id, sizeof(param)}, {value.num, value.den}};
|
||||
return mmal_port_parameter_set(port, ¶m.hdr);
|
||||
}
|
||||
|
||||
/** Helper function to get the value of a rational parameter */
|
||||
MMAL_STATUS_T mmal_port_parameter_get_rational(MMAL_PORT_T *port, uint32_t id, MMAL_RATIONAL_T *value)
|
||||
{
|
||||
MMAL_PARAMETER_RATIONAL_T param = {{id, sizeof(param)}, {0,0}};
|
||||
// coverity[overrun-buffer-val] Structure accessed correctly via size field
|
||||
MMAL_STATUS_T status = mmal_port_parameter_get(port, ¶m.hdr);
|
||||
if (status == MMAL_SUCCESS)
|
||||
*value = param.value;
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Helper function to set the value of a string parameter */
|
||||
MMAL_STATUS_T mmal_port_parameter_set_string(MMAL_PORT_T *port, uint32_t id, const char *value)
|
||||
{
|
||||
MMAL_PARAMETER_STRING_T *param = 0;
|
||||
MMAL_STATUS_T status;
|
||||
size_t param_size = sizeof(param->hdr) + strlen(value) + 1;
|
||||
|
||||
param = calloc(1, param_size);
|
||||
if (!param)
|
||||
return MMAL_ENOMEM;
|
||||
|
||||
param->hdr.id = id;
|
||||
param->hdr.size = param_size;
|
||||
memcpy(param->str, value, strlen(value)+1);
|
||||
status = mmal_port_parameter_set(port, ¶m->hdr);
|
||||
free(param);
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Helper function to set a MMAL_PARAMETER_URI_T parameter on a port */
|
||||
MMAL_STATUS_T mmal_util_port_set_uri(MMAL_PORT_T *port, const char *uri)
|
||||
{
|
||||
return mmal_port_parameter_set_string(port, MMAL_PARAMETER_URI, uri);
|
||||
}
|
||||
|
||||
/** Helper function to set the value of an array of bytes parameter */
|
||||
MMAL_STATUS_T mmal_port_parameter_set_bytes(MMAL_PORT_T *port, uint32_t id,
|
||||
const uint8_t *data, unsigned int size)
|
||||
{
|
||||
MMAL_PARAMETER_BYTES_T *param = 0;
|
||||
MMAL_STATUS_T status;
|
||||
size_t param_size = sizeof(param->hdr) + size;
|
||||
|
||||
param = calloc(1, param_size);
|
||||
if (!param)
|
||||
return MMAL_ENOMEM;
|
||||
|
||||
param->hdr.id = id;
|
||||
param->hdr.size = param_size;
|
||||
memcpy(param->data, data, size);
|
||||
status = mmal_port_parameter_set(port, ¶m->hdr);
|
||||
free(param);
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Set the display region.
|
||||
* @param port port to configure
|
||||
* @param region region
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
|
||||
MMAL_STATUS_T mmal_util_set_display_region(MMAL_PORT_T *port,
|
||||
MMAL_DISPLAYREGION_T *region)
|
||||
{
|
||||
region->hdr.id = MMAL_PARAMETER_DISPLAYREGION;
|
||||
region->hdr.size = sizeof(*region);
|
||||
return mmal_port_parameter_set(port, ®ion->hdr);
|
||||
}
|
||||
|
||||
MMAL_STATUS_T mmal_util_camera_use_stc_timestamp(MMAL_PORT_T *port, MMAL_CAMERA_STC_MODE_T mode)
|
||||
{
|
||||
MMAL_PARAMETER_CAMERA_STC_MODE_T param =
|
||||
{{MMAL_PARAMETER_USE_STC, sizeof(MMAL_PARAMETER_CAMERA_STC_MODE_T)},mode};
|
||||
return mmal_port_parameter_set(port, ¶m.hdr);
|
||||
}
|
||||
|
||||
MMAL_STATUS_T mmal_util_get_core_port_stats(MMAL_PORT_T *port,
|
||||
MMAL_CORE_STATS_DIR dir,
|
||||
MMAL_BOOL_T reset,
|
||||
MMAL_CORE_STATISTICS_T *stats)
|
||||
{
|
||||
MMAL_PARAMETER_CORE_STATISTICS_T param;
|
||||
MMAL_STATUS_T ret;
|
||||
|
||||
memset(¶m, 0, sizeof(param));
|
||||
param.hdr.id = MMAL_PARAMETER_CORE_STATISTICS;
|
||||
param.hdr.size = sizeof(param);
|
||||
param.dir = dir;
|
||||
param.reset = reset;
|
||||
// coverity[overrun-buffer-val] Structure accessed correctly via size field
|
||||
ret = mmal_port_parameter_get(port, ¶m.hdr);
|
||||
if (ret == MMAL_SUCCESS)
|
||||
*stats = param.stats;
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MMAL_UTIL_PARAMS_H
|
||||
#define MMAL_UTIL_PARAMS_H
|
||||
|
||||
#include "mmal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Utility functions to set some common parameters.
|
||||
*/
|
||||
|
||||
/** Helper function to set the value of a boolean parameter.
|
||||
* @param port port on which to set the parameter
|
||||
* @param id parameter id
|
||||
* @param value value to set the parameter to
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_port_parameter_set_boolean(MMAL_PORT_T *port, uint32_t id, MMAL_BOOL_T value);
|
||||
|
||||
/** Helper function to get the value of a boolean parameter.
|
||||
* @param port port on which to get the parameter
|
||||
* @param id parameter id
|
||||
* @param value pointer to where the value will be returned
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_port_parameter_get_boolean(MMAL_PORT_T *port, uint32_t id, MMAL_BOOL_T *value);
|
||||
|
||||
/** Helper function to set the value of a 64 bits unsigned integer parameter.
|
||||
* @param port port on which to set the parameter
|
||||
* @param id parameter id
|
||||
* @param value value to set the parameter to
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_port_parameter_set_uint64(MMAL_PORT_T *port, uint32_t id, uint64_t value);
|
||||
|
||||
/** Helper function to get the value of a 64 bits unsigned integer parameter.
|
||||
* @param port port on which to get the parameter
|
||||
* @param id parameter id
|
||||
* @param value pointer to where the value will be returned
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_port_parameter_get_uint64(MMAL_PORT_T *port, uint32_t id, uint64_t *value);
|
||||
|
||||
/** Helper function to set the value of a 64 bits signed integer parameter.
|
||||
* @param port port on which to set the parameter
|
||||
* @param id parameter id
|
||||
* @param value value to set the parameter to
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_port_parameter_set_int64(MMAL_PORT_T *port, uint32_t id, int64_t value);
|
||||
|
||||
/** Helper function to get the value of a 64 bits signed integer parameter.
|
||||
* @param port port on which to get the parameter
|
||||
* @param id parameter id
|
||||
* @param value pointer to where the value will be returned
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_port_parameter_get_int64(MMAL_PORT_T *port, uint32_t id, int64_t *value);
|
||||
|
||||
/** Helper function to set the value of a 32 bits unsigned integer parameter.
|
||||
* @param port port on which to set the parameter
|
||||
* @param id parameter id
|
||||
* @param value value to set the parameter to
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_port_parameter_set_uint32(MMAL_PORT_T *port, uint32_t id, uint32_t value);
|
||||
|
||||
/** Helper function to get the value of a 32 bits unsigned integer parameter.
|
||||
* @param port port on which to get the parameter
|
||||
* @param id parameter id
|
||||
* @param value pointer to where the value will be returned
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_port_parameter_get_uint32(MMAL_PORT_T *port, uint32_t id, uint32_t *value);
|
||||
|
||||
/** Helper function to set the value of a 32 bits signed integer parameter.
|
||||
* @param port port on which to set the parameter
|
||||
* @param id parameter id
|
||||
* @param value value to set the parameter to
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_port_parameter_set_int32(MMAL_PORT_T *port, uint32_t id, int32_t value);
|
||||
|
||||
/** Helper function to get the value of a 32 bits signed integer parameter.
|
||||
* @param port port on which to get the parameter
|
||||
* @param id parameter id
|
||||
* @param value pointer to where the value will be returned
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_port_parameter_get_int32(MMAL_PORT_T *port, uint32_t id, int32_t *value);
|
||||
|
||||
/** Helper function to set the value of a rational parameter.
|
||||
* @param port port on which to set the parameter
|
||||
* @param id parameter id
|
||||
* @param value value to set the parameter to
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_port_parameter_set_rational(MMAL_PORT_T *port, uint32_t id, MMAL_RATIONAL_T value);
|
||||
|
||||
/** Helper function to get the value of a rational parameter.
|
||||
* @param port port on which to get the parameter
|
||||
* @param id parameter id
|
||||
* @param value pointer to where the value will be returned
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_port_parameter_get_rational(MMAL_PORT_T *port, uint32_t id, MMAL_RATIONAL_T *value);
|
||||
|
||||
/** Helper function to set the value of a string parameter.
|
||||
* @param port port on which to set the parameter
|
||||
* @param id parameter id
|
||||
* @param value null-terminated string value
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_port_parameter_set_string(MMAL_PORT_T *port, uint32_t id, const char *value);
|
||||
|
||||
/** Helper function to set the value of an array of bytes parameter.
|
||||
* @param port port on which to set the parameter
|
||||
* @param id parameter id
|
||||
* @param data pointer to the array of bytes
|
||||
* @param size size of the array of bytes
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_port_parameter_set_bytes(MMAL_PORT_T *port, uint32_t id,
|
||||
const uint8_t *data, unsigned int size);
|
||||
|
||||
/** Helper function to set a MMAL_PARAMETER_URI_T parameter on a port.
|
||||
* @param port port on which to set the parameter
|
||||
* @param uri URI string
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_util_port_set_uri(MMAL_PORT_T *port, const char *uri);
|
||||
|
||||
/** Set the display region.
|
||||
* @param port port to configure
|
||||
* @param region region
|
||||
*
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_util_set_display_region(MMAL_PORT_T *port,
|
||||
MMAL_DISPLAYREGION_T *region);
|
||||
|
||||
/** Tell the camera to use the STC for timestamps rather than the clock.
|
||||
*
|
||||
* @param port port to configure
|
||||
* @param mode STC mode to use
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_util_camera_use_stc_timestamp(MMAL_PORT_T *port, MMAL_CAMERA_STC_MODE_T mode);
|
||||
|
||||
/** Get the MMAL core statistics for a given port.
|
||||
*
|
||||
* @param port port to query
|
||||
* @param dir port direction
|
||||
* @param reset reset the stats as well
|
||||
* @param stats filled in with results
|
||||
* @return MMAL_SUCCESS or error
|
||||
*/
|
||||
MMAL_STATUS_T mmal_util_get_core_port_stats(MMAL_PORT_T *port, MMAL_CORE_STATS_DIR dir, MMAL_BOOL_T reset,
|
||||
MMAL_CORE_STATISTICS_T *stats);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include "interface/mmal/util/mmal_util_rational.h"
|
||||
|
||||
#define Q16_ONE (1 << 16)
|
||||
|
||||
#define ABS(v) (((v) < 0) ? -(v) : (v))
|
||||
|
||||
/** Calculate the greatest common denominator between 2 integers.
|
||||
* Avoids division. */
|
||||
static int32_t gcd(int32_t a, int32_t b)
|
||||
{
|
||||
int shift;
|
||||
|
||||
if (a == 0 || b == 0)
|
||||
return 1;
|
||||
|
||||
a = ABS(a);
|
||||
b = ABS(b);
|
||||
for (shift = 0; !((a | b) & 0x01); shift++)
|
||||
a >>= 1, b >>= 1;
|
||||
|
||||
while (a > 0)
|
||||
{
|
||||
while (!(a & 0x01))
|
||||
a >>= 1;
|
||||
while (!(b & 0x01))
|
||||
b >>= 1;
|
||||
if (a >= b)
|
||||
a = (a - b) >> 1;
|
||||
else
|
||||
b = (b - a) >> 1;
|
||||
}
|
||||
return b << shift;
|
||||
}
|
||||
|
||||
/** Calculate a + b. */
|
||||
MMAL_RATIONAL_T mmal_rational_add(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b)
|
||||
{
|
||||
MMAL_RATIONAL_T result;
|
||||
int32_t g = gcd(a.den, b.den);
|
||||
a.den /= g;
|
||||
a.num = a.num * (b.den / g) + b.num * a.den;
|
||||
g = gcd(a.num, g);
|
||||
a.num /= g;
|
||||
a.den *= b.den / g;
|
||||
|
||||
result.num = a.num;
|
||||
result.den = a.den;
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Calculate a - b. */
|
||||
MMAL_RATIONAL_T mmal_rational_subtract(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b)
|
||||
{
|
||||
b.num = -b.num;
|
||||
return mmal_rational_add(a, b);
|
||||
}
|
||||
|
||||
/** Calculate a * b */
|
||||
MMAL_RATIONAL_T mmal_rational_multiply(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b)
|
||||
{
|
||||
MMAL_RATIONAL_T result;
|
||||
int32_t gcd1 = gcd(a.num, b.den);
|
||||
int32_t gcd2 = gcd(b.num, a.den);
|
||||
result.num = (a.num / gcd1) * (b.num / gcd2);
|
||||
result.den = (a.den / gcd2) * (b.den / gcd1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Calculate a / b */
|
||||
MMAL_RATIONAL_T mmal_rational_divide(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b)
|
||||
{
|
||||
MMAL_RATIONAL_T result;
|
||||
int32_t gcd1, gcd2;
|
||||
|
||||
if (b.num == 0)
|
||||
{
|
||||
vcos_assert(0);
|
||||
return a;
|
||||
}
|
||||
|
||||
if (a.num == 0)
|
||||
return a;
|
||||
|
||||
gcd1 = gcd(a.num, b.num);
|
||||
gcd2 = gcd(b.den, a.den);
|
||||
result.num = (a.num / gcd1) * (b.den / gcd2);
|
||||
result.den = (a.den / gcd2) * (b.num / gcd1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Convert a rational number to a signed 32-bit Q16 number. */
|
||||
int32_t mmal_rational_to_fixed_16_16(MMAL_RATIONAL_T rational)
|
||||
{
|
||||
int64_t result = (int64_t)rational.num << 16;
|
||||
if (rational.den)
|
||||
result /= rational.den;
|
||||
|
||||
if (result > INT_MAX)
|
||||
result = INT_MAX;
|
||||
else if (result < INT_MIN)
|
||||
result = INT_MIN;
|
||||
|
||||
return (int32_t)result;
|
||||
}
|
||||
|
||||
/** Convert a rational number to a signed 32-bit Q16 number. */
|
||||
MMAL_RATIONAL_T mmal_rational_from_fixed_16_16(int32_t fixed)
|
||||
{
|
||||
MMAL_RATIONAL_T result = { fixed, Q16_ONE };
|
||||
mmal_rational_simplify(&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Reduce a rational number to it's simplest form. */
|
||||
void mmal_rational_simplify(MMAL_RATIONAL_T *rational)
|
||||
{
|
||||
int g = gcd(rational->num, rational->den);
|
||||
rational->num /= g;
|
||||
rational->den /= g;
|
||||
}
|
||||
|
||||
/** Tests for equality */
|
||||
MMAL_BOOL_T mmal_rational_equal(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b)
|
||||
{
|
||||
if (a.num != b.num && a.num * (int64_t)b.num == 0)
|
||||
return MMAL_FALSE;
|
||||
return a.num * (int64_t)b.den == b.num * (int64_t)a.den;
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MMAL_UTIL_RATIONAL_H
|
||||
#define MMAL_UTIL_RATIONAL_H
|
||||
|
||||
#include "interface/mmal/mmal_types.h"
|
||||
|
||||
/** \defgroup MmalRationalUtilities Rational Utility Functions
|
||||
* \ingroup MmalUtilities
|
||||
* The rational utility functions allow easy manipulation of rational numbers.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Add 2 rational numbers.
|
||||
* It is assumed that both input rational numbers are in
|
||||
* their simplest form.
|
||||
*
|
||||
* @param a First operand
|
||||
* @param b Second operand
|
||||
*
|
||||
* @return a + b
|
||||
*/
|
||||
MMAL_RATIONAL_T mmal_rational_add(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b);
|
||||
|
||||
/** Subtract 2 rational numbers.
|
||||
* It is assumed that both input rational numbers are in
|
||||
* their simplest form.
|
||||
*
|
||||
* @param a First operand
|
||||
* @param b Second operand
|
||||
*
|
||||
* @return a - b
|
||||
*/
|
||||
MMAL_RATIONAL_T mmal_rational_subtract(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b);
|
||||
|
||||
/** Multiply 2 rational numbers.
|
||||
* It is assumed that both input rational numbers are in
|
||||
* their simplest form.
|
||||
*
|
||||
* @param a First operand
|
||||
* @param b Second operand
|
||||
*
|
||||
* @return a * b
|
||||
*/
|
||||
MMAL_RATIONAL_T mmal_rational_multiply(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b);
|
||||
|
||||
/** Divide 2 rational numbers.
|
||||
* It is assumed that both input rational numbers are in
|
||||
* their simplest form.
|
||||
*
|
||||
* @param a First operand
|
||||
* @param b Second operand
|
||||
*
|
||||
* @return a / b
|
||||
*/
|
||||
MMAL_RATIONAL_T mmal_rational_divide(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b);
|
||||
|
||||
/** Convert a rational number to a 32-bit signed Q16 number.
|
||||
* Saturation will occur for rational numbers with an absolute
|
||||
* value greater than 32768.
|
||||
*
|
||||
* @param rational Rational number to convert
|
||||
*
|
||||
* @return 32-bit signed Q16 number
|
||||
*/
|
||||
int32_t mmal_rational_to_fixed_16_16(MMAL_RATIONAL_T rational);
|
||||
|
||||
/** Convert a signed 32-bit Q16 number to a rational number.
|
||||
*
|
||||
* @param fixed Signed 32-bit Q16 number to convert
|
||||
*
|
||||
* @return Rational number
|
||||
*/
|
||||
MMAL_RATIONAL_T mmal_rational_from_fixed_16_16(int32_t fixed);
|
||||
|
||||
/** Reduce a rational number to it's simplest form.
|
||||
*
|
||||
* @param rational Rational number to simplify
|
||||
*/
|
||||
void mmal_rational_simplify(MMAL_RATIONAL_T *rational);
|
||||
|
||||
/** Test 2 rational numbers for equality.
|
||||
*
|
||||
* @param a First operand
|
||||
* @param b Second operand
|
||||
*
|
||||
* @return true if equal
|
||||
*/
|
||||
MMAL_BOOL_T mmal_rational_equal(MMAL_RATIONAL_T a, MMAL_RATIONAL_T b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user