123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- /*
- 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;
- }
|