1/*
2Copyright (c) 2012, Broadcom Europe Ltd
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the copyright holder nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#include "interface/vmcs_host/khronos/IL/OMX_Broadcom.h"
29#include "mmalomx.h"
30#include "mmalomx_parameters.h"
31#include "mmalomx_util_params.h"
32#include "mmalomx_roles.h"
33#include "mmalomx_registry.h"
34#include "mmalomx_logging.h"
35#include <util/mmal_util.h>
36#include <util/mmal_util_params.h>
37#include <util/mmal_util_rational.h>
38
39#define PARAM_GET_PORT(port, component, index) \
40 if (index >= component->ports_num) return OMX_ErrorBadPortIndex; \
41 port = &component->ports[index]
42
43#define MMALOMX_PARAM_GENERIC_MAX 256
44
45/** A structure capable of holding any OMX parameter that contains a port */
46typedef struct MMALOMX_PARAM_OMX_GENERIC_T
47{
48 MMALOMX_PARAM_OMX_HEADER_T header;
49 uint8_t data[MMALOMX_PARAM_GENERIC_MAX];
50} MMALOMX_PARAM_OMX_GENERIC_T;
51
52/** A structure capable of holding any OMX parameter that doesn't contain a port */
53typedef struct MMALOMX_PARAM_OMX_GENERIC_PORTLESS_T
54{
55 MMALOMX_PARAM_OMX_HEADER_PORTLESS_T hdr;
56 uint8_t data[MMALOMX_PARAM_GENERIC_MAX];
57} MMALOMX_PARAM_OMX_GENERIC_PORTLESS_T;
58
59/** A structure capable of holding any MMAL parameter */
60typedef struct MMALOMX_PARAM_MMAL_GENERIC_T
61{
62 MMAL_PARAMETER_HEADER_T header;
63 uint8_t data[MMALOMX_PARAM_GENERIC_MAX];
64} MMALOMX_PARAM_MMAL_GENERIC_T;
65
66static OMX_ERRORTYPE mmalomx_parameter_set_xlat(MMALOMX_COMPONENT_T *component,
67 OMX_INDEXTYPE nParamIndex, OMX_PTR pParam)
68{
69 const MMALOMX_PARAM_TRANSLATION_T *xlat = mmalomx_find_parameter_from_omx_id(nParamIndex);
70 MMALOMX_PARAM_OMX_HEADER_T *omx_header = (MMALOMX_PARAM_OMX_HEADER_T *)pParam;
71 MMALOMX_PARAM_MMAL_GENERIC_T mmal_generic;
72 MMAL_PARAMETER_HEADER_T *mmal_header = &mmal_generic.header;
73 MMAL_PORT_T *mmal_port = component->mmal->control;
74 MMAL_STATUS_T status;
75
76 if (!xlat)
77 {
78 LOG_DEBUG("no translation for omx id 0x%08x", nParamIndex);
79 return OMX_ErrorNotImplemented;
80 }
81
82 if (!xlat->portless)
83 {
84 if (omx_header->nSize < sizeof(*omx_header))
85 return OMX_ErrorBadParameter;
86 if (omx_header->nPortIndex >= component->ports_num)
87 return OMX_ErrorBadPortIndex;
88 mmal_port = component->ports[omx_header->nPortIndex].mmal;
89 }
90
91 if (omx_header->nSize < xlat->omx_size)
92 return OMX_ErrorBadParameter;
93
94 /* Handle the direct case first */
95 if (xlat->type == MMALOMX_PARAM_TRANSLATION_TYPE_DIRECT)
96 {
97 mmal_header = (MMAL_PARAMETER_HEADER_T *)(((uint8_t *)pParam) + (xlat->portless ? 0 : 4));
98 mmal_generic.header = *mmal_header;
99 mmal_header->size = omx_header->nSize - (xlat->portless ? 0 : 4);
100 mmal_header->id = xlat->mmal_id;
101 status = mmal_port_parameter_set(mmal_port, mmal_header);
102 *mmal_header = mmal_generic.header;
103 return mmalil_error_to_omx(status);
104 }
105
106 if (!xlat->fn.generic && !xlat->fn.simple)
107 {
108 // FIXME
109 return OMX_ErrorNotImplemented;
110 }
111
112 // FIXME: check size of mmal_generic is sufficient
113 if (sizeof(mmal_generic) < xlat->mmal_size)
114 return OMX_ErrorBadParameter;
115
116 mmal_header->size = xlat->mmal_size;
117 mmal_header->id = xlat->mmal_id;
118 if (xlat->fn.generic)
119 status = xlat->fn.generic(MMALOMX_PARAM_MAPPING_TO_MMAL, xlat, mmal_header, pParam, mmal_port);
120 else
121 status = xlat->fn.simple(MMALOMX_PARAM_MAPPING_TO_MMAL, mmal_header, pParam);
122 if (status != MMAL_SUCCESS)
123 goto error;
124
125 status = mmal_port_parameter_set(mmal_port, mmal_header);
126
127 error:
128 return mmalil_error_to_omx(status);
129}
130
131static OMX_ERRORTYPE mmalomx_parameter_get_xlat(MMALOMX_COMPONENT_T *component,
132 OMX_INDEXTYPE nParamIndex, OMX_PTR pParam)
133{
134 const MMALOMX_PARAM_TRANSLATION_T *xlat = mmalomx_find_parameter_from_omx_id(nParamIndex);
135 MMALOMX_PARAM_OMX_HEADER_T *omx_header = (MMALOMX_PARAM_OMX_HEADER_T *)pParam;
136 MMALOMX_PARAM_MMAL_GENERIC_T mmal_generic;
137 MMAL_PARAMETER_HEADER_T *mmal_header = &mmal_generic.header;
138 MMAL_PORT_T *mmal_port = component->mmal->control;
139 MMAL_STATUS_T status = MMAL_SUCCESS;
140
141 if (!xlat)
142 return OMX_ErrorNotImplemented;
143
144 if (!xlat->portless)
145 {
146 if (omx_header->nSize < sizeof(*omx_header))
147 return OMX_ErrorBadParameter;
148 if (omx_header->nPortIndex >= component->ports_num)
149 return OMX_ErrorBadPortIndex;
150 mmal_port = component->ports[omx_header->nPortIndex].mmal;
151 }
152
153 if (omx_header->nSize < xlat->omx_size)
154 return OMX_ErrorBadParameter;
155
156 /* Handle the direct case first */
157 if (xlat->type == MMALOMX_PARAM_TRANSLATION_TYPE_DIRECT)
158 {
159 OMX_U32 size;
160 mmal_header = (MMAL_PARAMETER_HEADER_T *)(((uint8_t *)pParam) + (xlat->portless ? 0 : 4));
161 mmal_generic.header = *mmal_header;
162 mmal_header->size = omx_header->nSize - (xlat->portless ? 0 : 4);
163 mmal_header->id = xlat->mmal_id;
164 status = mmal_port_parameter_get(mmal_port, mmal_header);
165 *mmal_header = mmal_generic.header;
166 size = mmal_header->size + (xlat->portless ? 0 : 4);
167 omx_header->nSize = size;
168 return mmalil_error_to_omx(status);
169 }
170
171 if (xlat->fn.custom)
172 {
173 return mmalil_error_to_omx(xlat->fn.custom(MMALOMX_PARAM_MAPPING_TO_OMX, xlat, mmal_header,
174 pParam, mmal_port));
175 }
176
177 if (xlat->fn.list)
178 {
179 OMX_U32 index, elements;
180 mmal_header = mmal_port_parameter_alloc_get(mmal_port, xlat->mmal_id,
181 10*xlat->mmal_size, &status);
182 if (!mmal_header)
183 return OMX_ErrorInsufficientResources;
184
185 /* Check we're not requesting too much */
186 index = *(OMX_U32 *)(((uint8_t *)pParam) + xlat->xlat_enum_num);
187 elements = (mmal_header->size - sizeof(MMAL_PARAMETER_HEADER_T)) /
188 (xlat->mmal_size - sizeof(MMAL_PARAMETER_HEADER_T));
189 if (index >= elements)
190 {
191 vcos_free(mmal_header);
192 return OMX_ErrorNoMore;
193 }
194 status = xlat->fn.list(MMALOMX_PARAM_MAPPING_TO_OMX, xlat, index, mmal_header, pParam, mmal_port);
195 vcos_free(mmal_header);
196 return mmalil_error_to_omx(status);
197 }
198
199 if (!xlat->fn.generic && !xlat->fn.simple)
200 {
201 // FIXME
202 return OMX_ErrorNotImplemented;
203 }
204
205 // FIXME: check size of mmal_generic is sufficient
206 if (sizeof(mmal_generic) < xlat->mmal_size)
207 return OMX_ErrorBadParameter;
208
209 mmal_header->size = xlat->mmal_size;
210 mmal_header->id = xlat->mmal_id;
211
212 if (xlat->double_translation)
213 {
214 if (xlat->fn.generic)
215 status = xlat->fn.generic(MMALOMX_PARAM_MAPPING_TO_MMAL, xlat, mmal_header, pParam, mmal_port);
216 else
217 status = xlat->fn.simple(MMALOMX_PARAM_MAPPING_TO_MMAL, mmal_header, pParam);
218 }
219 if (status != MMAL_SUCCESS)
220 goto error;
221
222 status = mmal_port_parameter_get(mmal_port, mmal_header);
223 if (status != MMAL_SUCCESS)
224 goto error;
225
226 if (xlat->fn.generic)
227 status = xlat->fn.generic(MMALOMX_PARAM_MAPPING_TO_OMX, xlat, mmal_header, pParam, mmal_port);
228 else
229 status = xlat->fn.simple(MMALOMX_PARAM_MAPPING_TO_OMX, mmal_header, pParam);
230
231 error:
232 return mmalil_error_to_omx(status);
233}
234
235OMX_ERRORTYPE mmalomx_parameter_extension_index_get(OMX_STRING cParameterName,
236 OMX_INDEXTYPE *pIndex)
237{
238 const MMALOMX_PARAM_TRANSLATION_T *xlat;
239 MMAL_BOOL_T config = MMAL_FALSE;
240 unsigned int i = 0;
241
242 /* Check we're dealing with our extensions */
243 if (!vcos_strncasecmp(cParameterName, MMALOMX_COMPONENT_PREFIX, sizeof(MMALOMX_COMPONENT_PREFIX)-1))
244 return OMX_ErrorNotImplemented;
245 cParameterName += sizeof(MMALOMX_COMPONENT_PREFIX)-1;
246
247 /* Check if we're dealing with a config or param */
248 if (!vcos_strncasecmp(cParameterName, "index.config.", sizeof("index.config.")-1))
249 config = MMAL_TRUE;
250 if (!config && vcos_strncasecmp(cParameterName, "index.param.", sizeof("index.param.")-1))
251 return OMX_ErrorNotImplemented;
252 if (config)
253 cParameterName += sizeof("index.config.")-1;
254 else
255 cParameterName += sizeof("index.param.")-1;
256
257 /* Loop through all the */
258 while ((xlat = mmalomx_find_parameter_enum(i++)) != NULL)
259 {
260 const char *name = xlat->omx_name;
261
262 /* We only report vendor extensions */
263 if (xlat->omx_id < OMX_IndexVendorStartUnused)
264 continue;
265
266 /* Strip out the standard prefix */
267 if (config)
268 {
269 if (!strncmp(name, "OMX_IndexConfigBrcm", sizeof("OMX_IndexConfigBrcm")-1))
270 name += sizeof("OMX_IndexConfigBrcm")-1;
271 else if (!strncmp(name, "OMX_IndexConfig", sizeof("OMX_IndexConfig")-1))
272 name += sizeof("OMX_IndexConfig")-1;
273 else continue;
274 }
275 else
276 {
277 if (!strncmp(name, "OMX_IndexParamBrcm", sizeof("OMX_IndexParamBrcm")-1))
278 name += sizeof("OMX_IndexParamBrcm")-1;
279 else if (!strncmp(name, "OMX_IndexParam", sizeof("OMX_IndexParam")-1))
280 name += sizeof("OMX_IndexParam")-1;
281 else continue;
282 }
283
284 /* Compare the last part of the name */
285 if (!vcos_strcasecmp(name, cParameterName))
286 {
287 *pIndex = xlat->omx_id;
288 return OMX_ErrorNone;
289 }
290 }
291
292 return OMX_ErrorNotImplemented;
293}
294
295/*****************************************************************************/
296static OMX_ERRORTYPE mmalomx_get_video_param(MMALOMX_PORT_T *port,
297 uint32_t *profile, uint32_t *level, uint32_t *intraperiod)
298{
299 MMAL_PARAMETER_VIDEO_PROFILE_T mmal_param = {{MMAL_PARAMETER_PROFILE, sizeof(mmal_param)},
300 {{(MMAL_VIDEO_PROFILE_T)0, (MMAL_VIDEO_LEVEL_T)0}}};
301
302 *profile = *level = *intraperiod = 0;
303
304 mmal_port_parameter_get_uint32(port->mmal, MMAL_PARAMETER_INTRAPERIOD, intraperiod);
305
306 if (mmal_port_parameter_get(port->mmal, &mmal_param.hdr) == MMAL_SUCCESS)
307 {
308 *profile = mmalil_video_profile_to_omx(mmal_param.profile[0].profile);
309 *level = mmalil_video_level_to_omx(mmal_param.profile[0].level);
310 }
311
312 return OMX_ErrorNone;
313}
314
315/*****************************************************************************/
316OMX_ERRORTYPE mmalomx_parameter_get(MMALOMX_COMPONENT_T *component,
317 OMX_INDEXTYPE nParamIndex, OMX_PTR pParam)
318{
319 MMALOMX_PORT_T *port = NULL;
320
321 switch(nParamIndex)
322 {
323 /* All OMX_IndexParamVideo parameters are only partially implemented
324 * and we try and use sensible hard-coded values for the rest. */
325 case OMX_IndexParamVideoAvc:
326 {
327 OMX_VIDEO_PARAM_AVCTYPE *param = (OMX_VIDEO_PARAM_AVCTYPE *)pParam;
328 uint32_t profile, level, intraperiod;
329 PARAM_GET_PORT(port, component, param->nPortIndex);
330 if (param->nSize < sizeof(*param))
331 return OMX_ErrorBadParameter;
332 memset(&param->nSliceHeaderSpacing, 0,
333 param->nSize - offsetof(OMX_VIDEO_PARAM_AVCTYPE, nSliceHeaderSpacing));
334
335 mmalomx_get_video_param(port, &profile, &level, &intraperiod);
336 param->eProfile = (OMX_VIDEO_AVCPROFILETYPE)profile;
337 param->eLevel = (OMX_VIDEO_AVCLEVELTYPE)level;
338 param->nPFrames = intraperiod - 1;
339 param->bUseHadamard = OMX_TRUE;
340 param->nRefFrames = 1;
341 param->nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
342 param->bFrameMBsOnly = OMX_TRUE;
343 if (param->eProfile != OMX_VIDEO_AVCProfileBaseline)
344 param->bEntropyCodingCABAC = OMX_TRUE;
345 param->eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
346 }
347 return OMX_ErrorNone;
348 case OMX_IndexParamVideoMpeg4:
349 {
350 OMX_VIDEO_PARAM_MPEG4TYPE *param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pParam;
351 uint32_t profile, level, intraperiod;
352 PARAM_GET_PORT(port, component, param->nPortIndex);
353 if (param->nSize < sizeof(*param))
354 return OMX_ErrorBadParameter;
355 memset(&param->nSliceHeaderSpacing, 0,
356 param->nSize - offsetof(OMX_VIDEO_PARAM_MPEG4TYPE, nSliceHeaderSpacing));
357
358 mmalomx_get_video_param(port, &profile, &level, &intraperiod);
359 param->eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)profile;
360 param->eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)level;
361 param->nPFrames = intraperiod - 1;
362 param->bACPred = OMX_TRUE;
363 param->nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
364 }
365 return OMX_ErrorNone;
366 case OMX_IndexParamVideoH263:
367 {
368 OMX_VIDEO_PARAM_H263TYPE *param = (OMX_VIDEO_PARAM_H263TYPE *)pParam;
369 uint32_t profile, level, intraperiod;
370 PARAM_GET_PORT(port, component, param->nPortIndex);
371 if (param->nSize < sizeof(*param))
372 return OMX_ErrorBadParameter;
373 memset(&param->nPFrames, 0,
374 param->nSize - offsetof(OMX_VIDEO_PARAM_H263TYPE, nPFrames));
375
376 mmalomx_get_video_param(port, &profile, &level, &intraperiod);
377 param->eProfile = (OMX_VIDEO_H263PROFILETYPE)profile;
378 param->eLevel = (OMX_VIDEO_H263LEVELTYPE)level;
379 param->nPFrames = intraperiod - 1;
380 param->nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
381 }
382 return OMX_ErrorNone;
383 case OMX_IndexParamVideoMpeg2:
384 case OMX_IndexParamVideoWmv:
385 case OMX_IndexParamVideoRv:
386 {
387 OMX_FORMAT_PARAM_TYPE *param = (OMX_FORMAT_PARAM_TYPE *)pParam;
388 PARAM_GET_PORT(port, component, param->common.nPortIndex);
389 OMX_U32 offset = offsetof(OMX_PARAM_U32TYPE, nU32);
390 if (param->common.nSize > sizeof(port->format_param) ||
391 param->common.nSize < offset)
392 return OMX_ErrorBadParameter;
393 memcpy(&param->common.nU32, &port->format_param.common.nU32,
394 param->common.nSize - offset);
395 return OMX_ErrorNone;
396 }
397 case OMX_IndexParamAudioPcm:
398 case OMX_IndexParamAudioAac:
399 case OMX_IndexParamAudioMp3:
400 case OMX_IndexParamAudioDdp:
401 {
402 OMX_FORMAT_PARAM_TYPE *param = (OMX_FORMAT_PARAM_TYPE *)pParam;
403 PARAM_GET_PORT(port, component, param->common.nPortIndex);
404 OMX_U32 offset = offsetof(OMX_PARAM_U32TYPE, nU32);
405 if (param->common.nSize > sizeof(port->format_param) ||
406 param->common.nSize < offset)
407 return OMX_ErrorBadParameter;
408 memcpy(&param->common.nU32, &port->format_param.common.nU32,
409 param->common.nSize - offset);
410 mmalil_format_to_omx_audio_param(param, NULL, port->mmal->format);
411 return OMX_ErrorNone;
412 }
413 case OMX_IndexParamBrcmPixelAspectRatio:
414 {
415 OMX_CONFIG_POINTTYPE *param = (OMX_CONFIG_POINTTYPE *)pParam;
416 PARAM_GET_PORT(port, component, param->nPortIndex);
417 param->nX = port->mmal->format->es->video.par.num;
418 param->nY = port->mmal->format->es->video.par.den;
419 return OMX_ErrorNone;
420 }
421 case OMX_IndexParamColorSpace:
422 {
423 OMX_PARAM_COLORSPACETYPE *param = (OMX_PARAM_COLORSPACETYPE *)pParam;
424 PARAM_GET_PORT(port, component, param->nPortIndex);
425 param->eColorSpace = mmalil_color_space_to_omx(port->mmal->format->es->video.color_space);
426 return OMX_ErrorNone;
427 }
428 case OMX_IndexConfigCommonOutputCrop:
429 {
430 OMX_CONFIG_RECTTYPE *param = (OMX_CONFIG_RECTTYPE *)pParam;
431 PARAM_GET_PORT(port, component, param->nPortIndex);
432 param->nLeft = port->mmal->format->es->video.crop.x;
433 param->nTop = port->mmal->format->es->video.crop.y;
434 param->nWidth = port->mmal->format->es->video.width;
435 if (port->mmal->format->es->video.crop.width)
436 param->nWidth = port->mmal->format->es->video.crop.width;
437 param->nHeight = port->mmal->format->es->video.height;
438 if (port->mmal->format->es->video.crop.height)
439 param->nHeight = port->mmal->format->es->video.crop.height;
440 return OMX_ErrorNone;
441 }
442 case OMX_IndexConfigCommonScale:
443 {
444 OMX_CONFIG_SCALEFACTORTYPE *param = (OMX_CONFIG_SCALEFACTORTYPE *)pParam;
445 PARAM_GET_PORT(port, component, param->nPortIndex);
446 param->xWidth = param->xHeight = 1<<16;
447 if (port->mmal->format->es->video.par.num &&
448 port->mmal->format->es->video.par.den)
449 param->xWidth = mmal_rational_to_fixed_16_16(port->mmal->format->es->video.par);
450 return OMX_ErrorNone;
451 }
452 default:
453 return mmalomx_parameter_get_xlat(component, nParamIndex, pParam);
454 }
455
456 return OMX_ErrorNotImplemented;
457}
458
459/*****************************************************************************/
460static OMX_ERRORTYPE mmalomx_set_video_param(MMALOMX_PORT_T *port,
461 uint32_t profile, uint32_t level, uint32_t intraperiod)
462{
463 MMAL_PARAMETER_VIDEO_PROFILE_T mmal_param = {{MMAL_PARAMETER_PROFILE, sizeof(mmal_param)},
464 {{(MMAL_VIDEO_PROFILE_T)0, (MMAL_VIDEO_LEVEL_T)0}}};
465 OMX_VIDEO_CODINGTYPE coding =
466 mmalil_encoding_to_omx_video_coding(port->mmal->format->encoding);
467
468 if (mmal_port_parameter_set_uint32(port->mmal, MMAL_PARAMETER_INTRAPERIOD,
469 intraperiod) != MMAL_SUCCESS)
470 return OMX_ErrorBadParameter;
471
472 mmal_param.profile[0].profile = (MMAL_VIDEO_PROFILE_T)
473 mmalil_omx_video_profile_to_mmal(profile, coding);
474 mmal_param.profile[0].level = (MMAL_VIDEO_LEVEL_T)
475 mmalil_omx_video_level_to_mmal(level, coding);
476 if (mmal_port_parameter_set(port->mmal, &mmal_param.hdr) != MMAL_SUCCESS)
477 return OMX_ErrorBadParameter;
478
479 return OMX_ErrorNone;
480}
481
482/*****************************************************************************/
483OMX_ERRORTYPE mmalomx_parameter_set(MMALOMX_COMPONENT_T *component,
484 OMX_INDEXTYPE nParamIndex, OMX_PTR pParam)
485{
486 MMALOMX_PORT_T *port = NULL;
487
488 switch(nParamIndex)
489 {
490 /* All OMX_IndexParamVideo parameters are only partially implemented */
491 case OMX_IndexParamVideoAvc:
492 {
493 OMX_VIDEO_PARAM_AVCTYPE *param = (OMX_VIDEO_PARAM_AVCTYPE *)pParam;
494 PARAM_GET_PORT(port, component, param->nPortIndex);
495 if (param->nSize < sizeof(*param))
496 return OMX_ErrorBadParameter;
497 return mmalomx_set_video_param(port, param->eProfile, param->eLevel,
498 param->nPFrames + 1);
499 }
500 case OMX_IndexParamVideoMpeg4:
501 {
502 OMX_VIDEO_PARAM_MPEG4TYPE *param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pParam;
503 PARAM_GET_PORT(port, component, param->nPortIndex);
504 if (param->nSize < sizeof(*param))
505 return OMX_ErrorBadParameter;
506 return mmalomx_set_video_param(port, param->eProfile, param->eLevel,
507 param->nPFrames + 1);
508 }
509 case OMX_IndexParamVideoH263:
510 {
511 OMX_VIDEO_PARAM_H263TYPE *param = (OMX_VIDEO_PARAM_H263TYPE *)pParam;
512 PARAM_GET_PORT(port, component, param->nPortIndex);
513 if (param->nSize < sizeof(*param))
514 return OMX_ErrorBadParameter;
515 return mmalomx_set_video_param(port, param->eProfile, param->eLevel,
516 param->nPFrames + 1);
517 }
518 case OMX_IndexParamVideoMpeg2:
519 case OMX_IndexParamVideoWmv:
520 case OMX_IndexParamVideoRv:
521 {
522 OMX_FORMAT_PARAM_TYPE *param = (OMX_FORMAT_PARAM_TYPE *)pParam;
523 OMX_U32 offset = offsetof(OMX_PARAM_U32TYPE, nU32);
524 PARAM_GET_PORT(port, component, param->common.nPortIndex);
525 if (param->common.nSize > sizeof(port->format_param) ||
526 param->common.nSize < offset)
527 return OMX_ErrorBadParameter;
528 memcpy(&port->format_param.common.nU32, &param->common.nU32,
529 param->common.nSize - offset);
530 return OMX_ErrorNone;
531 }
532 case OMX_IndexParamAudioPcm:
533 case OMX_IndexParamAudioAac:
534 case OMX_IndexParamAudioMp3:
535 case OMX_IndexParamAudioDdp:
536 {
537 OMX_FORMAT_PARAM_TYPE *param = (OMX_FORMAT_PARAM_TYPE *)pParam;
538 OMX_U32 offset = offsetof(OMX_PARAM_U32TYPE, nU32);
539 PARAM_GET_PORT(port, component, param->common.nPortIndex);
540 if (param->common.nSize > sizeof(port->format_param) ||
541 param->common.nSize < offset)
542 return OMX_ErrorBadParameter;
543 memcpy(&port->format_param.common.nU32, &param->common.nU32,
544 param->common.nSize - offset);
545 mmalil_omx_audio_param_to_format(port->mmal->format,
546 mmalil_omx_audio_param_index_to_coding(nParamIndex), param);
547 mmal_port_format_commit(port->mmal);
548 return OMX_ErrorNone;
549 }
550 case OMX_IndexParamBrcmPixelAspectRatio:
551 {
552 OMX_CONFIG_POINTTYPE *param = (OMX_CONFIG_POINTTYPE *)pParam;
553 PARAM_GET_PORT(port, component, param->nPortIndex);
554 port->mmal->format->es->video.par.num = param->nX;
555 port->mmal->format->es->video.par.den = param->nY;
556 mmal_rational_simplify(&port->mmal->format->es->video.par);
557 return mmalil_error_to_omx(mmal_port_format_commit(port->mmal));
558 }
559 case OMX_IndexParamColorSpace:
560 {
561 OMX_PARAM_COLORSPACETYPE *param = (OMX_PARAM_COLORSPACETYPE *)pParam;
562 PARAM_GET_PORT(port, component, param->nPortIndex);
563 port->mmal->format->es->video.color_space = mmalil_omx_color_space_to_mmal(param->eColorSpace);
564 return mmalil_error_to_omx(mmal_port_format_commit(port->mmal));
565 }
566 case OMX_IndexParamBrcmVideoCroppingDisable:
567 {
568 OMX_CONFIG_PORTBOOLEANTYPE *param = (OMX_CONFIG_PORTBOOLEANTYPE *)pParam;
569 PARAM_GET_PORT(port, component, param->nPortIndex);
570 port->no_cropping = param->bEnabled;
571 return OMX_ErrorNone;
572 }
573 default:
574 return mmalomx_parameter_set_xlat(component, nParamIndex, pParam);
575 }
576
577 return OMX_ErrorNotImplemented;
578}
579