1 /*****************************************************************************
2 * utils.c: helper functions
3 *****************************************************************************
4 * Copyright (C) 2010 VLC authors and VideoLAN
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_codec.h>
34 #include <vlc_block_helper.h>
40 /*****************************************************************************
41 * Events utility functions
42 *****************************************************************************/
43 OMX_ERRORTYPE PostOmxEvent(decoder_t *p_dec, OMX_EVENTTYPE event,
44 OMX_U32 data_1, OMX_U32 data_2, OMX_PTR event_data)
46 decoder_sys_t *p_sys = p_dec->p_sys;
49 p_event = malloc(sizeof(OmxEvent));
50 if(!p_event) return OMX_ErrorInsufficientResources;
52 p_event->event = event;
53 p_event->data_1 = data_1;
54 p_event->data_2 = data_2;
55 p_event->event_data = event_data;
58 vlc_mutex_lock(&p_sys->mutex);
59 *p_sys->pp_last_event = p_event;
60 p_sys->pp_last_event = &p_event->next;
61 vlc_cond_signal(&p_sys->cond);
62 vlc_mutex_unlock(&p_sys->mutex);
66 OMX_ERRORTYPE WaitForOmxEvent(decoder_t *p_dec, OMX_EVENTTYPE *event,
67 OMX_U32 *data_1, OMX_U32 *data_2, OMX_PTR *event_data)
69 decoder_sys_t *p_sys = p_dec->p_sys;
72 vlc_mutex_lock(&p_sys->mutex);
75 vlc_cond_timedwait(&p_sys->cond, &p_sys->mutex, mdate()+CLOCK_FREQ);
77 p_event = p_sys->p_events;
80 p_sys->p_events = p_event->next;
81 if(!p_sys->p_events) p_sys->pp_last_event = &p_sys->p_events;
84 vlc_mutex_unlock(&p_sys->mutex);
88 if(event) *event = p_event->event;
89 if(data_1) *data_1 = p_event->data_1;
90 if(data_2) *data_2 = p_event->data_2;
91 if(event_data) *event_data = p_event->event_data;
96 return OMX_ErrorTimeout;
99 OMX_ERRORTYPE WaitForSpecificOmxEvent(decoder_t *p_dec,
100 OMX_EVENTTYPE specific_event, OMX_U32 *data_1, OMX_U32 *data_2,
103 OMX_ERRORTYPE status;
105 mtime_t before = mdate();
109 status = WaitForOmxEvent(p_dec, &event, data_1, data_2, event_data);
110 if(status != OMX_ErrorNone) return status;
112 if(event == specific_event) break;
113 if(mdate() - before > CLOCK_FREQ) return OMX_ErrorTimeout;
116 return OMX_ErrorNone;
119 /*****************************************************************************
120 * Picture utility functions
121 *****************************************************************************/
122 void CopyOmxPicture( int i_color_format, picture_t *p_pic,
124 int i_src_stride, uint8_t *p_src, int i_chroma_div )
128 int i_plane, i_width, i_line;
129 if( i_color_format == QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka )
131 qcom_convert(p_src, p_pic);
135 for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
137 if(i_plane == 1) i_src_stride /= i_chroma_div;
138 p_dst = p_pic->p[i_plane].p_pixels;
139 i_dst_stride = p_pic->p[i_plane].i_pitch;
140 i_width = p_pic->p[i_plane].i_visible_pitch;
142 for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines; i_line++ )
144 memcpy( p_dst, p_src, i_width );
145 p_src += i_src_stride;
146 p_dst += i_dst_stride;
148 /* Handle plane height, which may be indicated via nSliceHeight in OMX.
149 * The handling for chroma planes currently assumes vertically
150 * subsampled chroma, e.g. 422 planar wouldn't work right. */
151 if( i_plane == 0 && i_slice_height > p_pic->p[i_plane].i_visible_lines )
152 p_src += i_src_stride * (i_slice_height - p_pic->p[i_plane].i_visible_lines);
153 else if ( i_plane > 0 && i_slice_height/2 > p_pic->p[i_plane].i_visible_lines )
154 p_src += i_src_stride * (i_slice_height/2 - p_pic->p[i_plane].i_visible_lines);
158 void CopyVlcPicture( decoder_t *p_dec, OMX_BUFFERHEADERTYPE *p_header,
161 decoder_sys_t *p_sys = p_dec->p_sys;
162 int i_src_stride, i_dst_stride;
163 int i_plane, i_width, i_line;
164 uint8_t *p_dst, *p_src;
166 i_dst_stride = p_sys->out.i_frame_stride;
167 p_dst = p_header->pBuffer + p_header->nOffset;
169 for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
171 if(i_plane == 1) i_dst_stride /= p_sys->in.i_frame_stride_chroma_div;
172 p_src = p_pic->p[i_plane].p_pixels;
173 i_src_stride = p_pic->p[i_plane].i_pitch;
174 i_width = p_pic->p[i_plane].i_visible_pitch;
176 for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines; i_line++ )
178 memcpy( p_dst, p_src, i_width );
179 p_src += i_src_stride;
180 p_dst += i_dst_stride;
185 int IgnoreOmxDecoderPadding(const char *name)
187 // The list of decoders that signal padding properly is not necessary,
188 // since that is the default, but keep it here for reference. (This is
189 // only relevant for manufacturers that are known to have decoders with
190 // this kind of bug.)
192 static const char *padding_decoders[] = {
193 "OMX.SEC.AVC.Decoder",
199 static const char *nopadding_decoders[] = {
202 "OMX.SEC.MPEG4.Decoder",
207 for (const char **ptr = nopadding_decoders; *ptr; ptr++) {
208 if (!strcmp(*ptr, name))
214 /*****************************************************************************
215 * Logging utility functions
216 *****************************************************************************/
217 const char *StateToString(OMX_STATETYPE state)
219 static const char *psz_names[] = {
220 "OMX_StateInvalid", "OMX_StateLoaded", "OMX_StateIdle",
221 "OMX_StateExecuting", "OMX_StatePause", "OMX_StateWaitForResources",
225 if((unsigned int)state > sizeof(psz_names)/sizeof(char*)-1)
226 state = (OMX_STATETYPE)(sizeof(psz_names)/sizeof(char*)-1);
227 return psz_names[state];
230 const char *CommandToString(OMX_COMMANDTYPE command)
232 static const char *psz_names[] = {
233 "OMX_CommandStateSet", "OMX_CommandFlush", "OMX_CommandPortDisable",
234 "OMX_CommandPortEnable", "OMX_CommandMarkBuffer",
235 "OMX_Command unknown"
238 if((unsigned int)command > sizeof(psz_names)/sizeof(char*)-1)
239 command = (OMX_COMMANDTYPE)(sizeof(psz_names)/sizeof(char*)-1);
240 return psz_names[command];
243 const char *EventToString(OMX_EVENTTYPE event)
245 static const char *psz_names[] = {
246 "OMX_EventCmdComplete", "OMX_EventError", "OMX_EventMark",
247 "OMX_EventPortSettingsChanged", "OMX_EventBufferFlag",
248 "OMX_EventResourcesAcquired", "OMX_EventComponentResumed",
249 "OMX_EventDynamicResourcesAvailable", "OMX_EventPortFormatDetected",
253 if((unsigned int)event > sizeof(psz_names)/sizeof(char*)-1)
254 event = (OMX_EVENTTYPE)(sizeof(psz_names)/sizeof(char*)-1);
255 return psz_names[event];
258 const char *ErrorToString(OMX_ERRORTYPE error)
260 static const char *psz_names[] = {
261 "OMX_ErrorInsufficientResources", "OMX_ErrorUndefined",
262 "OMX_ErrorInvalidComponentName", "OMX_ErrorComponentNotFound",
263 "OMX_ErrorInvalidComponent", "OMX_ErrorBadParameter",
264 "OMX_ErrorNotImplemented", "OMX_ErrorUnderflow",
265 "OMX_ErrorOverflow", "OMX_ErrorHardware", "OMX_ErrorInvalidState",
266 "OMX_ErrorStreamCorrupt", "OMX_ErrorPortsNotCompatible",
267 "OMX_ErrorResourcesLost", "OMX_ErrorNoMore", "OMX_ErrorVersionMismatch",
268 "OMX_ErrorNotReady", "OMX_ErrorTimeout", "OMX_ErrorSameState",
269 "OMX_ErrorResourcesPreempted", "OMX_ErrorPortUnresponsiveDuringAllocation",
270 "OMX_ErrorPortUnresponsiveDuringDeallocation",
271 "OMX_ErrorPortUnresponsiveDuringStop", "OMX_ErrorIncorrectStateTransition",
272 "OMX_ErrorIncorrectStateOperation", "OMX_ErrorUnsupportedSetting",
273 "OMX_ErrorUnsupportedIndex", "OMX_ErrorBadPortIndex",
274 "OMX_ErrorPortUnpopulated", "OMX_ErrorComponentSuspended",
275 "OMX_ErrorDynamicResourcesUnavailable", "OMX_ErrorMbErrorsInFrame",
276 "OMX_ErrorFormatNotDetected", "OMX_ErrorContentPipeOpenFailed",
277 "OMX_ErrorContentPipeCreationFailed", "OMX_ErrorSeperateTablesUsed",
278 "OMX_ErrorTunnelingUnsupported",
282 if(error == OMX_ErrorNone) return "OMX_ErrorNone";
284 error -= OMX_ErrorInsufficientResources;
286 if((unsigned int)error > sizeof(psz_names)/sizeof(char*)-1)
287 error = (OMX_STATETYPE)(sizeof(psz_names)/sizeof(char*)-1);
288 return psz_names[error];
291 /*****************************************************************************
292 * fourcc -> omx id mapping
293 *****************************************************************************/
296 vlc_fourcc_t i_fourcc;
297 OMX_VIDEO_CODINGTYPE i_codec;
298 const char *psz_role;
300 } video_format_table[] =
302 { VLC_CODEC_MPGV, OMX_VIDEO_CodingMPEG2, "video_decoder.mpeg2" },
303 { VLC_CODEC_MP4V, OMX_VIDEO_CodingMPEG4, "video_decoder.mpeg4" },
304 { VLC_CODEC_H264, OMX_VIDEO_CodingAVC, "video_decoder.avc" },
305 { VLC_CODEC_H263, OMX_VIDEO_CodingH263, "video_decoder.h263" },
306 { VLC_CODEC_WMV1, OMX_VIDEO_CodingWMV, "video_decoder.wmv1" },
307 { VLC_CODEC_WMV2, OMX_VIDEO_CodingWMV, "video_decoder.wmv2" },
308 { VLC_CODEC_WMV3, OMX_VIDEO_CodingWMV, "video_decoder.wmv" },
309 { VLC_CODEC_VC1, OMX_VIDEO_CodingWMV, "video_decoder.wmv" },
310 { VLC_CODEC_MJPG, OMX_VIDEO_CodingMJPEG, "video_decoder.jpeg" },
311 { VLC_CODEC_MJPG, OMX_VIDEO_CodingMJPEG, "video_decoder.mjpeg" },
312 { VLC_CODEC_RV10, OMX_VIDEO_CodingRV, "video_decoder.rv" },
313 { VLC_CODEC_RV20, OMX_VIDEO_CodingRV, "video_decoder.rv" },
314 { VLC_CODEC_RV30, OMX_VIDEO_CodingRV, "video_decoder.rv" },
315 { VLC_CODEC_RV40, OMX_VIDEO_CodingRV, "video_decoder.rv" },
321 vlc_fourcc_t i_fourcc;
322 OMX_AUDIO_CODINGTYPE i_codec;
323 const char *psz_role;
325 } audio_format_table[] =
327 { VLC_CODEC_AMR_NB, OMX_AUDIO_CodingAMR, "audio_decoder.amrnb" },
328 { VLC_CODEC_AMR_WB, OMX_AUDIO_CodingAMR, "audio_decoder.amrwb" },
329 { VLC_CODEC_MP4A, OMX_AUDIO_CodingAAC, "audio_decoder.aac" },
330 { VLC_CODEC_S16N, OMX_AUDIO_CodingPCM, "audio_decoder.pcm" },
331 { VLC_CODEC_MP3, OMX_AUDIO_CodingMP3, "audio_decoder.mp3" },
337 vlc_fourcc_t i_fourcc;
338 OMX_VIDEO_CODINGTYPE i_codec;
339 const char *psz_role;
341 } video_enc_format_table[] =
343 { VLC_CODEC_MPGV, OMX_VIDEO_CodingMPEG2, "video_encoder.mpeg2" },
344 { VLC_CODEC_MP4V, OMX_VIDEO_CodingMPEG4, "video_encoder.mpeg4" },
345 { VLC_CODEC_H264, OMX_VIDEO_CodingAVC, "video_encoder.avc" },
346 { VLC_CODEC_H263, OMX_VIDEO_CodingH263, "video_encoder.h263" },
347 { VLC_CODEC_WMV1, OMX_VIDEO_CodingWMV, "video_encoder.wmv" },
348 { VLC_CODEC_WMV2, OMX_VIDEO_CodingWMV, "video_encoder.wmv" },
349 { VLC_CODEC_WMV3, OMX_VIDEO_CodingWMV, "video_encoder.wmv" },
350 { VLC_CODEC_MJPG, OMX_VIDEO_CodingMJPEG, "video_encoder.jpeg" },
351 { VLC_CODEC_RV10, OMX_VIDEO_CodingRV, "video_encoder.rv" },
352 { VLC_CODEC_RV20, OMX_VIDEO_CodingRV, "video_encoder.rv" },
353 { VLC_CODEC_RV30, OMX_VIDEO_CodingRV, "video_encoder.rv" },
354 { VLC_CODEC_RV40, OMX_VIDEO_CodingRV, "video_encoder.rv" },
360 vlc_fourcc_t i_fourcc;
361 OMX_AUDIO_CODINGTYPE i_codec;
362 const char *psz_role;
364 } audio_enc_format_table[] =
366 { VLC_CODEC_AMR_NB, OMX_AUDIO_CodingAMR, "audio_encoder.amrnb" },
367 { VLC_CODEC_AMR_WB, OMX_AUDIO_CodingAMR, "audio_encoder.amrwb" },
368 { VLC_CODEC_MP4A, OMX_AUDIO_CodingAAC, "audio_encoder.aac" },
369 { VLC_CODEC_S16N, OMX_AUDIO_CodingPCM, "audio_encoder.pcm" },
375 vlc_fourcc_t i_fourcc;
376 OMX_COLOR_FORMATTYPE i_codec;
377 unsigned int i_size_mul;
378 unsigned int i_line_mul;
379 unsigned int i_line_chroma_div;
381 } chroma_format_table[] =
383 { VLC_CODEC_I420, OMX_COLOR_FormatYUV420Planar, 3, 1, 2 },
384 { VLC_CODEC_I420, OMX_COLOR_FormatYUV420PackedPlanar, 3, 1, 2 },
385 { VLC_CODEC_NV12, OMX_COLOR_FormatYUV420SemiPlanar, 3, 1, 1 },
386 { VLC_CODEC_NV21, OMX_QCOM_COLOR_FormatYVU420SemiPlanar, 3, 1, 1 },
387 { VLC_CODEC_NV12, OMX_TI_COLOR_FormatYUV420PackedSemiPlanar, 3, 1, 2 },
388 { VLC_CODEC_NV12, QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka, 3, 1, 1 },
389 { VLC_CODEC_YUYV, OMX_COLOR_FormatYCbYCr, 4, 2, 0 },
390 { VLC_CODEC_YVYU, OMX_COLOR_FormatYCrYCb, 4, 2, 0 },
391 { VLC_CODEC_UYVY, OMX_COLOR_FormatCbYCrY, 4, 2, 0 },
392 { VLC_CODEC_VYUY, OMX_COLOR_FormatCrYCbY, 4, 2, 0 },
396 int GetOmxVideoFormat( vlc_fourcc_t i_fourcc,
397 OMX_VIDEO_CODINGTYPE *pi_omx_codec,
398 const char **ppsz_name )
402 i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc );
404 for( i = 0; video_format_table[i].i_codec != 0; i++ )
405 if( video_format_table[i].i_fourcc == i_fourcc ) break;
407 if( pi_omx_codec ) *pi_omx_codec = video_format_table[i].i_codec;
408 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( VIDEO_ES, i_fourcc );
409 return !!video_format_table[i].i_codec;
412 int GetVlcVideoFormat( OMX_VIDEO_CODINGTYPE i_omx_codec,
413 vlc_fourcc_t *pi_fourcc, const char **ppsz_name )
417 for( i = 0; video_format_table[i].i_codec != 0; i++ )
418 if( video_format_table[i].i_codec == i_omx_codec ) break;
420 if( pi_fourcc ) *pi_fourcc = video_format_table[i].i_fourcc;
421 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( VIDEO_ES,
422 video_format_table[i].i_fourcc );
423 return !!video_format_table[i].i_fourcc;
426 static const char *GetOmxVideoRole( vlc_fourcc_t i_fourcc )
430 i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc );
432 for( i = 0; video_format_table[i].i_codec != 0; i++ )
433 if( video_format_table[i].i_fourcc == i_fourcc ) break;
435 return video_format_table[i].psz_role;
438 static const char *GetOmxVideoEncRole( vlc_fourcc_t i_fourcc )
442 i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc );
444 for( i = 0; video_enc_format_table[i].i_codec != 0; i++ )
445 if( video_enc_format_table[i].i_fourcc == i_fourcc ) break;
447 return video_enc_format_table[i].psz_role;
450 int GetOmxAudioFormat( vlc_fourcc_t i_fourcc,
451 OMX_AUDIO_CODINGTYPE *pi_omx_codec,
452 const char **ppsz_name )
456 i_fourcc = vlc_fourcc_GetCodec( AUDIO_ES, i_fourcc );
458 for( i = 0; audio_format_table[i].i_codec != 0; i++ )
459 if( audio_format_table[i].i_fourcc == i_fourcc ) break;
461 if( pi_omx_codec ) *pi_omx_codec = audio_format_table[i].i_codec;
462 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( AUDIO_ES, i_fourcc );
463 return !!audio_format_table[i].i_codec;
466 int OmxToVlcAudioFormat( OMX_AUDIO_CODINGTYPE i_omx_codec,
467 vlc_fourcc_t *pi_fourcc, const char **ppsz_name )
471 for( i = 0; audio_format_table[i].i_codec != 0; i++ )
472 if( audio_format_table[i].i_codec == i_omx_codec ) break;
474 if( pi_fourcc ) *pi_fourcc = audio_format_table[i].i_fourcc;
475 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( AUDIO_ES,
476 audio_format_table[i].i_fourcc );
477 return !!audio_format_table[i].i_fourcc;
480 static const char *GetOmxAudioRole( vlc_fourcc_t i_fourcc )
484 i_fourcc = vlc_fourcc_GetCodec( AUDIO_ES, i_fourcc );
486 for( i = 0; audio_format_table[i].i_codec != 0; i++ )
487 if( audio_format_table[i].i_fourcc == i_fourcc ) break;
489 return audio_format_table[i].psz_role;
492 static const char *GetOmxAudioEncRole( vlc_fourcc_t i_fourcc )
496 i_fourcc = vlc_fourcc_GetCodec( AUDIO_ES, i_fourcc );
498 for( i = 0; audio_enc_format_table[i].i_codec != 0; i++ )
499 if( audio_enc_format_table[i].i_fourcc == i_fourcc ) break;
501 return audio_enc_format_table[i].psz_role;
504 const char *GetOmxRole( vlc_fourcc_t i_fourcc, int i_cat, bool b_enc )
507 return i_cat == VIDEO_ES ?
508 GetOmxVideoEncRole( i_fourcc ) : GetOmxAudioEncRole( i_fourcc );
510 return i_cat == VIDEO_ES ?
511 GetOmxVideoRole( i_fourcc ) : GetOmxAudioRole( i_fourcc );
514 int GetOmxChromaFormat( vlc_fourcc_t i_fourcc,
515 OMX_COLOR_FORMATTYPE *pi_omx_codec,
516 const char **ppsz_name )
520 i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc );
522 for( i = 0; chroma_format_table[i].i_codec != 0; i++ )
523 if( chroma_format_table[i].i_fourcc == i_fourcc ) break;
525 if( pi_omx_codec ) *pi_omx_codec = chroma_format_table[i].i_codec;
526 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( VIDEO_ES, i_fourcc );
527 return !!chroma_format_table[i].i_codec;
530 int GetVlcChromaFormat( OMX_COLOR_FORMATTYPE i_omx_codec,
531 vlc_fourcc_t *pi_fourcc, const char **ppsz_name )
535 for( i = 0; chroma_format_table[i].i_codec != 0; i++ )
536 if( chroma_format_table[i].i_codec == i_omx_codec ) break;
538 if( pi_fourcc ) *pi_fourcc = chroma_format_table[i].i_fourcc;
539 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( VIDEO_ES,
540 chroma_format_table[i].i_fourcc );
541 return !!chroma_format_table[i].i_fourcc;
544 int GetVlcChromaSizes( vlc_fourcc_t i_fourcc,
545 unsigned int width, unsigned int height,
546 unsigned int *size, unsigned int *pitch,
547 unsigned int *chroma_pitch_div )
551 i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc );
553 for( i = 0; chroma_format_table[i].i_codec != 0; i++ )
554 if( chroma_format_table[i].i_fourcc == i_fourcc ) break;
556 /* Align on macroblock boundary */
557 width = (width + 15) & ~0xF;
558 height = (height + 15) & ~0xF;
560 if( size ) *size = width * height * chroma_format_table[i].i_size_mul / 2;
561 if( pitch ) *pitch = width * chroma_format_table[i].i_line_mul;
562 if( chroma_pitch_div )
563 *chroma_pitch_div = chroma_format_table[i].i_line_chroma_div;
564 return !!chroma_format_table[i].i_codec;
567 /*****************************************************************************
568 * Functions to deal with audio format parameters
569 *****************************************************************************/
570 static const struct {
571 OMX_AUDIO_CODINGTYPE encoding;
574 } audio_encoding_param[] =
575 { { OMX_AUDIO_CodingPCM, OMX_IndexParamAudioPcm,
576 sizeof(OMX_AUDIO_PARAM_PCMMODETYPE) },
577 { OMX_AUDIO_CodingADPCM, OMX_IndexParamAudioAdpcm,
578 sizeof(OMX_AUDIO_PARAM_ADPCMTYPE) },
579 { OMX_AUDIO_CodingAMR, OMX_IndexParamAudioAmr,
580 sizeof(OMX_AUDIO_PARAM_AMRTYPE) },
581 { OMX_AUDIO_CodingG711, OMX_IndexParamAudioPcm,
582 sizeof(OMX_AUDIO_PARAM_PCMMODETYPE) },
583 { OMX_AUDIO_CodingG723, OMX_IndexParamAudioG723,
584 sizeof(OMX_AUDIO_PARAM_G723TYPE) },
585 { OMX_AUDIO_CodingG726, OMX_IndexParamAudioG726,
586 sizeof(OMX_AUDIO_PARAM_G726TYPE) },
587 { OMX_AUDIO_CodingG729, OMX_IndexParamAudioG729,
588 sizeof(OMX_AUDIO_PARAM_G729TYPE) },
589 { OMX_AUDIO_CodingAAC, OMX_IndexParamAudioAac,
590 sizeof(OMX_AUDIO_PARAM_AACPROFILETYPE) },
591 { OMX_AUDIO_CodingMP3, OMX_IndexParamAudioMp3,
592 sizeof(OMX_AUDIO_PARAM_MP3TYPE) },
593 { OMX_AUDIO_CodingSBC, OMX_IndexParamAudioSbc,
594 sizeof(OMX_AUDIO_PARAM_SBCTYPE) },
595 { OMX_AUDIO_CodingVORBIS, OMX_IndexParamAudioVorbis,
596 sizeof(OMX_AUDIO_PARAM_VORBISTYPE) },
597 { OMX_AUDIO_CodingWMA, OMX_IndexParamAudioWma,
598 sizeof(OMX_AUDIO_PARAM_WMATYPE) },
599 { OMX_AUDIO_CodingRA, OMX_IndexParamAudioRa,
600 sizeof(OMX_AUDIO_PARAM_RATYPE) },
601 { OMX_AUDIO_CodingUnused, 0, 0 }
604 static OMX_INDEXTYPE GetAudioParamFormatIndex(OMX_AUDIO_CODINGTYPE encoding)
608 for(i = 0; audio_encoding_param[i].encoding != OMX_AUDIO_CodingUnused &&
609 audio_encoding_param[i].encoding != encoding; i++);
611 return audio_encoding_param[i].index;
614 unsigned int GetAudioParamSize(OMX_INDEXTYPE index)
618 for(i = 0; audio_encoding_param[i].encoding != OMX_AUDIO_CodingUnused &&
619 audio_encoding_param[i].index != index; i++);
621 return audio_encoding_param[i].size;
624 OMX_ERRORTYPE SetAudioParameters(OMX_HANDLETYPE handle,
625 OmxFormatParam *param, OMX_U32 i_port, OMX_AUDIO_CODINGTYPE encoding,
626 uint8_t i_channels, unsigned int i_samplerate, unsigned int i_bitrate,
627 unsigned int i_bps, unsigned int i_blocksize)
633 case OMX_AUDIO_CodingPCM:
634 case OMX_AUDIO_CodingG711:
635 OMX_INIT_STRUCTURE(param->pcm);
636 param->pcm.nChannels = i_channels;
637 param->pcm.nSamplingRate = i_samplerate;
638 param->pcm.eNumData = OMX_NumericalDataSigned;
639 param->pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
640 param->pcm.eEndian = OMX_EndianLittle;
641 param->pcm.bInterleaved = OMX_TRUE;
642 param->pcm.nBitPerSample = i_bps;
643 param->pcm.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
646 param->pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
647 param->pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
650 case OMX_AUDIO_CodingADPCM:
651 OMX_INIT_STRUCTURE(param->adpcm);
652 param->adpcm.nChannels = i_channels;
653 param->adpcm.nSampleRate = i_samplerate;
654 param->adpcm.nBitsPerSample = i_bps;
656 case OMX_AUDIO_CodingAMR:
657 OMX_INIT_STRUCTURE(param->amr);
658 param->amr.nChannels = i_channels;
659 param->amr.nBitRate = i_bitrate;
660 param->amr.eAMRBandMode = OMX_AUDIO_AMRBandModeUnused;
661 param->amr.eAMRDTXMode = OMX_AUDIO_AMRDTXModeOff;
662 param->amr.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
664 case OMX_AUDIO_CodingG723:
665 OMX_INIT_STRUCTURE(param->g723);
666 param->g723.nChannels = i_channels;
667 param->g723.bDTX = OMX_FALSE;
668 param->g723.eBitRate = OMX_AUDIO_G723ModeUnused;
669 param->g723.bHiPassFilter = OMX_TRUE;
670 param->g723.bPostFilter = OMX_TRUE;
672 case OMX_AUDIO_CodingG726:
673 OMX_INIT_STRUCTURE(param->g726);
674 param->g726.nChannels = i_channels;
675 param->g726.eG726Mode = OMX_AUDIO_G726ModeUnused;
677 case OMX_AUDIO_CodingG729:
678 OMX_INIT_STRUCTURE(param->g729);
679 param->g729.nChannels = i_channels;
680 param->g729.bDTX = OMX_FALSE;
681 param->g729.eBitType = OMX_AUDIO_G729;
683 case OMX_AUDIO_CodingAAC:
684 OMX_INIT_STRUCTURE(param->aac);
685 param->aac.nChannels = i_channels;
686 param->aac.nSampleRate = i_samplerate;
687 param->aac.nBitRate = i_bitrate;
688 param->aac.nAudioBandWidth = 0;
689 param->aac.nFrameLength = 1024;
690 param->aac.nAACtools = OMX_AUDIO_AACToolAll;
691 param->aac.nAACERtools = OMX_AUDIO_AACERAll;
692 param->aac.eAACProfile = OMX_AUDIO_AACObjectLC;
693 param->aac.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
694 param->aac.eChannelMode = i_channels > 1 ?
695 OMX_AUDIO_ChannelModeStereo : OMX_AUDIO_ChannelModeMono;
697 case OMX_AUDIO_CodingMP3:
698 OMX_INIT_STRUCTURE(param->mp3);
699 param->mp3.nChannels = i_channels;
700 param->mp3.nSampleRate = i_samplerate;
701 param->mp3.nBitRate = i_bitrate;
702 param->mp3.eChannelMode = i_channels > 1 ?
703 OMX_AUDIO_ChannelModeStereo : OMX_AUDIO_ChannelModeMono;
704 param->mp3.eFormat = OMX_AUDIO_MP3StreamFormatMP1Layer3;
706 case OMX_AUDIO_CodingWMA:
707 OMX_INIT_STRUCTURE(param->wma);
708 param->wma.nChannels = i_channels;
709 param->wma.nBitRate = i_bitrate;
710 param->wma.eFormat = OMX_AUDIO_WMAFormatUnused;
711 param->wma.eProfile = OMX_AUDIO_WMAProfileUnused;
712 param->wma.nSamplingRate = i_samplerate;
713 param->wma.nBlockAlign = i_blocksize;
714 param->wma.nEncodeOptions = 0;
715 param->wma.nSuperBlockAlign = 0;
717 case OMX_AUDIO_CodingRA:
718 OMX_INIT_STRUCTURE(param->ra);
719 param->ra.nChannels = i_channels;
720 param->ra.nSamplingRate = i_samplerate;
721 param->ra.nBitsPerFrame = i_bps;
722 param->ra.nSamplePerFrame = 0;
723 param->ra.nCouplingQuantBits = 0;
724 param->ra.nCouplingStartRegion = 0;
725 param->ra.nNumRegions = 0;
726 param->ra.eFormat = OMX_AUDIO_RAFormatUnused;
728 case OMX_AUDIO_CodingVORBIS:
729 OMX_INIT_STRUCTURE(param->vorbis);
730 param->vorbis.nChannels = i_channels;
731 param->vorbis.nBitRate = i_bitrate;
732 param->vorbis.nMinBitRate = 0;
733 param->vorbis.nMaxBitRate = i_bitrate;
734 param->vorbis.nSampleRate = i_samplerate;
735 param->vorbis.nAudioBandWidth = 0;
736 param->vorbis.nQuality = 3;
737 param->vorbis.bManaged = OMX_FALSE;
738 param->vorbis.bDownmix = OMX_FALSE;
741 return OMX_ErrorBadParameter;
744 param->common.nPortIndex = i_port;
746 index = GetAudioParamFormatIndex(encoding);
747 return OMX_SetParameter(handle, index, param);
750 OMX_ERRORTYPE GetAudioParameters(OMX_HANDLETYPE handle,
751 OmxFormatParam *param, OMX_U32 i_port, OMX_AUDIO_CODINGTYPE encoding,
752 uint8_t *pi_channels, unsigned int *pi_samplerate,
753 unsigned int *pi_bitrate, unsigned int *pi_bps, unsigned int *pi_blocksize)
755 int i_channels = 0, i_samplerate = 0, i_bitrate = 0;
756 int i_bps = 0, i_blocksize = 0;
757 OMX_ERRORTYPE omx_error;
760 OMX_INIT_COMMON(param->common);
761 param->common.nPortIndex = i_port;
762 index = GetAudioParamFormatIndex(encoding);
763 if(!index) return OMX_ErrorNotImplemented;
765 param->common.nSize = GetAudioParamSize(index);
766 omx_error = OMX_GetParameter(handle, index, param);
767 if(omx_error != OMX_ErrorNone) return omx_error;
771 case OMX_AUDIO_CodingPCM:
772 case OMX_AUDIO_CodingG711:
773 i_channels = param->pcm.nChannels;
774 i_samplerate = param->pcm.nSamplingRate;
775 i_bps = param->pcm.nBitPerSample;
777 case OMX_AUDIO_CodingADPCM:
778 i_channels = param->adpcm.nChannels;
779 i_samplerate = param->adpcm.nSampleRate;
780 i_bps = param->adpcm.nBitsPerSample;
782 case OMX_AUDIO_CodingAMR:
783 i_channels = param->amr.nChannels;
784 i_bitrate = param->amr.nBitRate;
787 case OMX_AUDIO_CodingG723:
788 i_channels = param->g723.nChannels;
790 case OMX_AUDIO_CodingG726:
791 i_channels = param->g726.nChannels;
793 case OMX_AUDIO_CodingG729:
794 i_channels = param->g729.nChannels;
796 case OMX_AUDIO_CodingAAC:
797 i_channels = param->aac.nChannels;
798 i_samplerate = param->aac.nSampleRate;
799 i_bitrate = param->aac.nBitRate;
800 i_channels = param->aac.eChannelMode == OMX_AUDIO_ChannelModeStereo ? 2 : 1;
802 case OMX_AUDIO_CodingMP3:
803 i_channels = param->mp3.nChannels;
804 i_samplerate = param->mp3.nSampleRate;
805 i_bitrate = param->mp3.nBitRate;
806 i_channels = param->mp3.eChannelMode == OMX_AUDIO_ChannelModeStereo ? 2 : 1;
808 case OMX_AUDIO_CodingVORBIS:
809 i_channels = param->vorbis.nChannels;
810 i_bitrate = param->vorbis.nBitRate;
811 i_samplerate = param->vorbis.nSampleRate;
813 case OMX_AUDIO_CodingWMA:
814 i_channels = param->wma.nChannels;
815 i_bitrate = param->wma.nBitRate;
816 i_samplerate = param->wma.nSamplingRate;
817 i_blocksize = param->wma.nBlockAlign;
819 case OMX_AUDIO_CodingRA:
820 i_channels = param->ra.nChannels;
821 i_samplerate = param->ra.nSamplingRate;
822 i_bps = param->ra.nBitsPerFrame;
825 return OMX_ErrorBadParameter;
828 if(pi_channels) *pi_channels = i_channels;
829 if(pi_samplerate) *pi_samplerate = i_samplerate;
830 if(pi_bitrate) *pi_bitrate = i_bitrate;
831 if(pi_bps) *pi_bps = i_bps;
832 if(pi_blocksize) *pi_blocksize = i_blocksize;
833 return OMX_ErrorNone;
836 /*****************************************************************************
837 * PrintOmx: print component summary
838 *****************************************************************************/
839 void PrintOmx(decoder_t *p_dec, OMX_HANDLETYPE omx_handle, OMX_U32 i_port)
841 OMX_PARAM_PORTDEFINITIONTYPE definition;
842 OMX_PORT_PARAM_TYPE param;
843 OMX_ERRORTYPE omx_error;
846 /* Find the input / output ports */
847 OMX_INIT_STRUCTURE(param);
848 OMX_INIT_STRUCTURE(definition);
850 for(i = 0; i < 3; i++)
852 omx_error = OMX_GetParameter(omx_handle, OMX_IndexParamAudioInit + i, ¶m);
853 if(omx_error != OMX_ErrorNone) continue;
855 if(i_port == OMX_ALL)
856 msg_Dbg( p_dec, "found %i %s ports", (int)param.nPorts,
857 i == 0 ? "audio" : i == 1 ? "image" : "video" );
859 for(j = 0; j < param.nPorts; j++)
861 unsigned int i_samplerate, i_bitrate;
862 unsigned int i_bitspersample, i_blockalign;
864 OmxFormatParam format_param;
865 vlc_fourcc_t i_fourcc;
866 const char *psz_name;
867 OMX_CONFIG_RECTTYPE crop_rect;
869 if(i_port != OMX_ALL && i_port != param.nStartPortNumber + j)
872 /* Get port definition */
873 definition.nPortIndex = param.nStartPortNumber + j;
874 omx_error = OMX_GetParameter(omx_handle, OMX_IndexParamPortDefinition,
876 if(omx_error != OMX_ErrorNone) continue;
878 OMX_PARAM_U32TYPE u32param;
879 OMX_INIT_STRUCTURE(u32param);
880 u32param.nPortIndex = param.nStartPortNumber + j;
881 omx_error = OMX_GetParameter(omx_handle, OMX_IndexParamNumAvailableStreams,
884 msg_Dbg( p_dec, "-> %s %i (%i streams) (%i:%i:%i buffers) (%i,%i) %s",
885 definition.eDir == OMX_DirOutput ? "output" : "input",
886 (int)definition.nPortIndex, (int)u32param.nU32,
887 (int)definition.nBufferCountActual,
888 (int)definition.nBufferCountMin, (int)definition.nBufferSize,
889 (int)definition.bBuffersContiguous,
890 (int)definition.nBufferAlignment,
891 definition.bEnabled ? "enabled" : "disabled" );
893 switch(definition.eDomain)
895 case OMX_PortDomainVideo:
897 if(definition.format.video.eCompressionFormat)
898 GetVlcVideoFormat( definition.format.video.eCompressionFormat,
899 &i_fourcc, &psz_name );
901 GetVlcChromaFormat( definition.format.video.eColorFormat,
902 &i_fourcc, &psz_name );
904 OMX_INIT_STRUCTURE(crop_rect);
905 crop_rect.nPortIndex = definition.nPortIndex;
906 omx_error = OMX_GetConfig(omx_handle, OMX_IndexConfigCommonOutputCrop, &crop_rect);
907 if (omx_error != OMX_ErrorNone)
909 crop_rect.nLeft = crop_rect.nTop = 0;
910 crop_rect.nWidth = definition.format.video.nFrameWidth;
911 crop_rect.nHeight = definition.format.video.nFrameHeight;
914 msg_Dbg( p_dec, " -> video %s %ix%i@%.2f (%i,%i) (%i,%i) (%i,%i,%i,%i)", psz_name,
915 (int)definition.format.video.nFrameWidth,
916 (int)definition.format.video.nFrameHeight,
917 (float)definition.format.video.xFramerate/(float)(1<<16),
918 (int)definition.format.video.eCompressionFormat,
919 (int)definition.format.video.eColorFormat,
920 (int)definition.format.video.nStride,
921 (int)definition.format.video.nSliceHeight,
922 (int)crop_rect.nLeft, (int)crop_rect.nTop,
923 (int)crop_rect.nWidth, (int)crop_rect.nHeight);
926 case OMX_PortDomainAudio:
928 OmxToVlcAudioFormat( definition.format.audio.eEncoding,
929 &i_fourcc, &psz_name );
931 GetAudioParameters(omx_handle, &format_param,
932 definition.nPortIndex,
933 definition.format.audio.eEncoding,
934 &i_channels, &i_samplerate, &i_bitrate,
935 &i_bitspersample, &i_blockalign);
937 msg_Dbg( p_dec, " -> audio %s (%i) %i,%i,%i,%i,%i", psz_name,
938 (int)definition.format.audio.eEncoding,
939 i_channels, i_samplerate, i_bitrate, i_bitspersample,