1 /*****************************************************************************
2 * utils.c: helper functions
3 *****************************************************************************
4 * Copyright (C) 2010 the VideoLAN team
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 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 General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, 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>
39 #define OMX_QCOM_COLOR_FormatYVU420SemiPlanar 0x7FA30C00
41 /*****************************************************************************
42 * Events utility functions
43 *****************************************************************************/
44 OMX_ERRORTYPE PostOmxEvent(decoder_t *p_dec, OMX_EVENTTYPE event,
45 OMX_U32 data_1, OMX_U32 data_2, OMX_PTR event_data)
47 decoder_sys_t *p_sys = p_dec->p_sys;
50 p_event = malloc(sizeof(OmxEvent));
51 if(!p_event) return OMX_ErrorInsufficientResources;
53 p_event->event = event;
54 p_event->data_1 = data_1;
55 p_event->data_2 = data_2;
56 p_event->event_data = event_data;
59 vlc_mutex_lock(&p_sys->mutex);
60 *p_sys->pp_last_event = p_event;
61 p_sys->pp_last_event = &p_event->next;
62 vlc_cond_signal(&p_sys->cond);
63 vlc_mutex_unlock(&p_sys->mutex);
67 OMX_ERRORTYPE WaitForOmxEvent(decoder_t *p_dec, OMX_EVENTTYPE *event,
68 OMX_U32 *data_1, OMX_U32 *data_2, OMX_PTR *event_data)
70 decoder_sys_t *p_sys = p_dec->p_sys;
73 vlc_mutex_lock(&p_sys->mutex);
76 vlc_cond_timedwait(&p_sys->cond, &p_sys->mutex, mdate()+CLOCK_FREQ);
78 p_event = p_sys->p_events;
81 p_sys->p_events = p_event->next;
82 if(!p_sys->p_events) p_sys->pp_last_event = &p_sys->p_events;
85 vlc_mutex_unlock(&p_sys->mutex);
89 if(event) *event = p_event->event;
90 if(data_1) *data_1 = p_event->data_1;
91 if(data_2) *data_2 = p_event->data_2;
92 if(event_data) *event_data = p_event->event_data;
97 return OMX_ErrorTimeout;
100 OMX_ERRORTYPE WaitForSpecificOmxEvent(decoder_t *p_dec,
101 OMX_EVENTTYPE specific_event, OMX_U32 *data_1, OMX_U32 *data_2,
104 OMX_ERRORTYPE status;
106 mtime_t before = mdate();
110 status = WaitForOmxEvent(p_dec, &event, data_1, data_2, event_data);
111 if(status != OMX_ErrorNone) return status;
113 if(event == specific_event) break;
114 if(mdate() - before > CLOCK_FREQ) return OMX_ErrorTimeout;
117 return OMX_ErrorNone;
120 /*****************************************************************************
121 * Picture utility functions
122 *****************************************************************************/
123 void CopyOmxPicture( decoder_t *p_dec, picture_t *p_pic,
124 OMX_BUFFERHEADERTYPE *p_header, int i_slice_height )
126 decoder_sys_t *p_sys = p_dec->p_sys;
127 int i_src_stride, i_dst_stride;
128 int i_plane, i_width, i_line;
129 uint8_t *p_dst, *p_src;
131 i_src_stride = p_sys->out.i_frame_stride;
132 p_src = p_header->pBuffer + p_header->nOffset;
134 for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
136 if(i_plane == 1) i_src_stride /= p_sys->out.i_frame_stride_chroma_div;
137 p_dst = p_pic->p[i_plane].p_pixels;
138 i_dst_stride = p_pic->p[i_plane].i_pitch;
139 i_width = p_pic->p[i_plane].i_visible_pitch;
141 for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines; i_line++ )
143 vlc_memcpy( p_dst, p_src, i_width );
144 p_src += i_src_stride;
145 p_dst += i_dst_stride;
147 /* Handle plane height, which may be indicated via nSliceHeight in OMX.
148 * The handling for chroma planes currently assumes vertically
149 * subsampled chroma, e.g. 422 planar wouldn't work right. */
150 if( i_plane == 0 && i_slice_height > p_pic->p[i_plane].i_visible_lines )
151 p_src += i_src_stride * (i_slice_height - p_pic->p[i_plane].i_visible_lines);
152 else if ( i_plane > 0 && i_slice_height/2 > p_pic->p[i_plane].i_visible_lines )
153 p_src += i_src_stride * (i_slice_height/2 - p_pic->p[i_plane].i_visible_lines);
157 void CopyVlcPicture( decoder_t *p_dec, OMX_BUFFERHEADERTYPE *p_header,
160 decoder_sys_t *p_sys = p_dec->p_sys;
161 int i_src_stride, i_dst_stride;
162 int i_plane, i_width, i_line;
163 uint8_t *p_dst, *p_src;
165 i_dst_stride = p_sys->out.i_frame_stride;
166 p_dst = p_header->pBuffer + p_header->nOffset;
168 for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
170 if(i_plane == 1) i_dst_stride /= p_sys->in.i_frame_stride_chroma_div;
171 p_src = p_pic->p[i_plane].p_pixels;
172 i_src_stride = p_pic->p[i_plane].i_pitch;
173 i_width = p_pic->p[i_plane].i_visible_pitch;
175 for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines; i_line++ )
177 vlc_memcpy( p_dst, p_src, i_width );
178 p_src += i_src_stride;
179 p_dst += i_dst_stride;
184 /*****************************************************************************
185 * Logging utility functions
186 *****************************************************************************/
187 const char *StateToString(OMX_STATETYPE state)
189 static const char *psz_names[] = {
190 "OMX_StateInvalid", "OMX_StateLoaded", "OMX_StateIdle",
191 "OMX_StateExecuting", "OMX_StatePause", "OMX_StateWaitForResources",
195 if((unsigned int)state > sizeof(psz_names)/sizeof(char*)-1)
196 state = (OMX_STATETYPE)(sizeof(psz_names)/sizeof(char*)-1);
197 return psz_names[state];
200 const char *CommandToString(OMX_COMMANDTYPE command)
202 static const char *psz_names[] = {
203 "OMX_CommandStateSet", "OMX_CommandFlush", "OMX_CommandPortDisable",
204 "OMX_CommandPortEnable", "OMX_CommandMarkBuffer",
205 "OMX_Command unknown"
208 if((unsigned int)command > sizeof(psz_names)/sizeof(char*)-1)
209 command = (OMX_COMMANDTYPE)(sizeof(psz_names)/sizeof(char*)-1);
210 return psz_names[command];
213 const char *EventToString(OMX_EVENTTYPE event)
215 static const char *psz_names[] = {
216 "OMX_EventCmdComplete", "OMX_EventError", "OMX_EventMark",
217 "OMX_EventPortSettingsChanged", "OMX_EventBufferFlag",
218 "OMX_EventResourcesAcquired", "OMX_EventComponentResumed",
219 "OMX_EventDynamicResourcesAvailable", "OMX_EventPortFormatDetected",
223 if((unsigned int)event > sizeof(psz_names)/sizeof(char*)-1)
224 event = (OMX_EVENTTYPE)(sizeof(psz_names)/sizeof(char*)-1);
225 return psz_names[event];
228 const char *ErrorToString(OMX_ERRORTYPE error)
230 static const char *psz_names[] = {
231 "OMX_ErrorInsufficientResources", "OMX_ErrorUndefined",
232 "OMX_ErrorInvalidComponentName", "OMX_ErrorComponentNotFound",
233 "OMX_ErrorInvalidComponent", "OMX_ErrorBadParameter",
234 "OMX_ErrorNotImplemented", "OMX_ErrorUnderflow",
235 "OMX_ErrorOverflow", "OMX_ErrorHardware", "OMX_ErrorInvalidState",
236 "OMX_ErrorStreamCorrupt", "OMX_ErrorPortsNotCompatible",
237 "OMX_ErrorResourcesLost", "OMX_ErrorNoMore", "OMX_ErrorVersionMismatch",
238 "OMX_ErrorNotReady", "OMX_ErrorTimeout", "OMX_ErrorSameState",
239 "OMX_ErrorResourcesPreempted", "OMX_ErrorPortUnresponsiveDuringAllocation",
240 "OMX_ErrorPortUnresponsiveDuringDeallocation",
241 "OMX_ErrorPortUnresponsiveDuringStop", "OMX_ErrorIncorrectStateTransition",
242 "OMX_ErrorIncorrectStateOperation", "OMX_ErrorUnsupportedSetting",
243 "OMX_ErrorUnsupportedIndex", "OMX_ErrorBadPortIndex",
244 "OMX_ErrorPortUnpopulated", "OMX_ErrorComponentSuspended",
245 "OMX_ErrorDynamicResourcesUnavailable", "OMX_ErrorMbErrorsInFrame",
246 "OMX_ErrorFormatNotDetected", "OMX_ErrorContentPipeOpenFailed",
247 "OMX_ErrorContentPipeCreationFailed", "OMX_ErrorSeperateTablesUsed",
248 "OMX_ErrorTunnelingUnsupported",
252 if(error == OMX_ErrorNone) return "OMX_ErrorNone";
254 error -= OMX_ErrorInsufficientResources;
256 if((unsigned int)error > sizeof(psz_names)/sizeof(char*)-1)
257 error = (OMX_STATETYPE)(sizeof(psz_names)/sizeof(char*)-1);
258 return psz_names[error];
261 /*****************************************************************************
262 * fourcc -> omx id mapping
263 *****************************************************************************/
266 vlc_fourcc_t i_fourcc;
267 OMX_VIDEO_CODINGTYPE i_codec;
268 const char *psz_role;
270 } video_format_table[] =
272 { VLC_CODEC_MPGV, OMX_VIDEO_CodingMPEG2, "video_decoder.mpeg2" },
273 { VLC_CODEC_MP4V, OMX_VIDEO_CodingMPEG4, "video_decoder.mpeg4" },
274 { VLC_CODEC_H264, OMX_VIDEO_CodingAVC, "video_decoder.avc" },
275 { VLC_CODEC_H263, OMX_VIDEO_CodingH263, "video_decoder.h263" },
276 { VLC_CODEC_WMV1, OMX_VIDEO_CodingWMV, "video_decoder.wmv" },
277 { VLC_CODEC_WMV2, OMX_VIDEO_CodingWMV, "video_decoder.wmv" },
278 { VLC_CODEC_WMV3, OMX_VIDEO_CodingWMV, "video_decoder.wmv" },
279 { VLC_CODEC_MJPG, OMX_VIDEO_CodingMJPEG, "video_decoder.jpeg" },
280 { VLC_CODEC_RV10, OMX_VIDEO_CodingRV, "video_decoder.rv" },
281 { VLC_CODEC_RV20, OMX_VIDEO_CodingRV, "video_decoder.rv" },
282 { VLC_CODEC_RV30, OMX_VIDEO_CodingRV, "video_decoder.rv" },
283 { VLC_CODEC_RV40, OMX_VIDEO_CodingRV, "video_decoder.rv" },
289 vlc_fourcc_t i_fourcc;
290 OMX_AUDIO_CODINGTYPE i_codec;
291 const char *psz_role;
293 } audio_format_table[] =
295 { VLC_CODEC_AMR_NB, OMX_AUDIO_CodingAMR, "audio_decoder.amr" },
296 { VLC_CODEC_AMR_WB, OMX_AUDIO_CodingAMR, "audio_decoder.amr" },
297 { VLC_CODEC_MP4A, OMX_AUDIO_CodingAAC, "audio_decoder.aac" },
298 { VLC_CODEC_S16N, OMX_AUDIO_CodingPCM, "audio_decoder.pcm" },
304 vlc_fourcc_t i_fourcc;
305 OMX_VIDEO_CODINGTYPE i_codec;
306 const char *psz_role;
308 } video_enc_format_table[] =
310 { VLC_CODEC_MPGV, OMX_VIDEO_CodingMPEG2, "video_encoder.mpeg2" },
311 { VLC_CODEC_MP4V, OMX_VIDEO_CodingMPEG4, "video_encoder.mpeg4" },
312 { VLC_CODEC_H264, OMX_VIDEO_CodingAVC, "video_encoder.avc" },
313 { VLC_CODEC_H263, OMX_VIDEO_CodingH263, "video_encoder.h263" },
314 { VLC_CODEC_WMV1, OMX_VIDEO_CodingWMV, "video_encoder.wmv" },
315 { VLC_CODEC_WMV2, OMX_VIDEO_CodingWMV, "video_encoder.wmv" },
316 { VLC_CODEC_WMV3, OMX_VIDEO_CodingWMV, "video_encoder.wmv" },
317 { VLC_CODEC_MJPG, OMX_VIDEO_CodingMJPEG, "video_encoder.jpeg" },
318 { VLC_CODEC_RV10, OMX_VIDEO_CodingRV, "video_encoder.rv" },
319 { VLC_CODEC_RV20, OMX_VIDEO_CodingRV, "video_encoder.rv" },
320 { VLC_CODEC_RV30, OMX_VIDEO_CodingRV, "video_encoder.rv" },
321 { VLC_CODEC_RV40, OMX_VIDEO_CodingRV, "video_encoder.rv" },
327 vlc_fourcc_t i_fourcc;
328 OMX_AUDIO_CODINGTYPE i_codec;
329 const char *psz_role;
331 } audio_enc_format_table[] =
333 { VLC_CODEC_AMR_NB, OMX_AUDIO_CodingAMR, "audio_encoder.amr" },
334 { VLC_CODEC_AMR_WB, OMX_AUDIO_CodingAMR, "audio_encoder.amr" },
335 { VLC_CODEC_MP4A, OMX_AUDIO_CodingAAC, "audio_encoder.aac" },
336 { VLC_CODEC_S16N, OMX_AUDIO_CodingPCM, "audio_encoder.pcm" },
342 vlc_fourcc_t i_fourcc;
343 OMX_COLOR_FORMATTYPE i_codec;
344 unsigned int i_size_mul;
345 unsigned int i_line_mul;
346 unsigned int i_line_chroma_div;
348 } chroma_format_table[] =
350 { VLC_CODEC_I420, OMX_COLOR_FormatYUV420Planar, 3, 1, 2 },
351 { VLC_CODEC_I420, OMX_COLOR_FormatYUV420PackedPlanar, 3, 1, 2 },
352 { VLC_CODEC_NV12, OMX_COLOR_FormatYUV420SemiPlanar, 3, 1, 1 },
353 { VLC_CODEC_NV21, OMX_QCOM_COLOR_FormatYVU420SemiPlanar, 3, 1, 1 },
354 { VLC_CODEC_YUYV, OMX_COLOR_FormatYCbYCr, 4, 2, 0 },
355 { VLC_CODEC_YVYU, OMX_COLOR_FormatYCrYCb, 4, 2, 0 },
356 { VLC_CODEC_UYVY, OMX_COLOR_FormatCbYCrY, 4, 2, 0 },
357 { VLC_CODEC_VYUY, OMX_COLOR_FormatCrYCbY, 4, 2, 0 },
361 int GetOmxVideoFormat( vlc_fourcc_t i_fourcc,
362 OMX_VIDEO_CODINGTYPE *pi_omx_codec,
363 const char **ppsz_name )
367 i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc );
369 for( i = 0; video_format_table[i].i_codec != 0; i++ )
370 if( video_format_table[i].i_fourcc == i_fourcc ) break;
372 if( pi_omx_codec ) *pi_omx_codec = video_format_table[i].i_codec;
373 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( VIDEO_ES, i_fourcc );
374 return !!video_format_table[i].i_codec;
377 int GetVlcVideoFormat( OMX_VIDEO_CODINGTYPE i_omx_codec,
378 vlc_fourcc_t *pi_fourcc, const char **ppsz_name )
382 for( i = 0; video_format_table[i].i_codec != 0; i++ )
383 if( video_format_table[i].i_codec == i_omx_codec ) break;
385 if( pi_fourcc ) *pi_fourcc = video_format_table[i].i_fourcc;
386 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( VIDEO_ES,
387 video_format_table[i].i_fourcc );
388 return !!video_format_table[i].i_fourcc;
391 static const char *GetOmxVideoRole( vlc_fourcc_t i_fourcc )
395 i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc );
397 for( i = 0; video_format_table[i].i_codec != 0; i++ )
398 if( video_format_table[i].i_fourcc == i_fourcc ) break;
400 return video_format_table[i].psz_role;
403 static const char *GetOmxVideoEncRole( vlc_fourcc_t i_fourcc )
407 i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc );
409 for( i = 0; video_enc_format_table[i].i_codec != 0; i++ )
410 if( video_enc_format_table[i].i_fourcc == i_fourcc ) break;
412 return video_enc_format_table[i].psz_role;
415 int GetOmxAudioFormat( vlc_fourcc_t i_fourcc,
416 OMX_AUDIO_CODINGTYPE *pi_omx_codec,
417 const char **ppsz_name )
421 i_fourcc = vlc_fourcc_GetCodec( AUDIO_ES, i_fourcc );
423 for( i = 0; audio_format_table[i].i_codec != 0; i++ )
424 if( audio_format_table[i].i_fourcc == i_fourcc ) break;
426 if( pi_omx_codec ) *pi_omx_codec = audio_format_table[i].i_codec;
427 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( AUDIO_ES, i_fourcc );
428 return !!audio_format_table[i].i_codec;
431 int GetVlcAudioFormat( OMX_AUDIO_CODINGTYPE i_omx_codec,
432 vlc_fourcc_t *pi_fourcc, const char **ppsz_name )
436 for( i = 0; audio_format_table[i].i_codec != 0; i++ )
437 if( audio_format_table[i].i_codec == i_omx_codec ) break;
439 if( pi_fourcc ) *pi_fourcc = audio_format_table[i].i_fourcc;
440 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( AUDIO_ES,
441 audio_format_table[i].i_fourcc );
442 return !!audio_format_table[i].i_fourcc;
445 static const char *GetOmxAudioRole( vlc_fourcc_t i_fourcc )
449 i_fourcc = vlc_fourcc_GetCodec( AUDIO_ES, i_fourcc );
451 for( i = 0; audio_format_table[i].i_codec != 0; i++ )
452 if( audio_format_table[i].i_fourcc == i_fourcc ) break;
454 return audio_format_table[i].psz_role;
457 static const char *GetOmxAudioEncRole( vlc_fourcc_t i_fourcc )
461 i_fourcc = vlc_fourcc_GetCodec( AUDIO_ES, i_fourcc );
463 for( i = 0; audio_enc_format_table[i].i_codec != 0; i++ )
464 if( audio_enc_format_table[i].i_fourcc == i_fourcc ) break;
466 return audio_enc_format_table[i].psz_role;
469 const char *GetOmxRole( vlc_fourcc_t i_fourcc, int i_cat, bool b_enc )
472 return i_cat == VIDEO_ES ?
473 GetOmxVideoEncRole( i_fourcc ) : GetOmxAudioEncRole( i_fourcc );
475 return i_cat == VIDEO_ES ?
476 GetOmxVideoRole( i_fourcc ) : GetOmxAudioRole( i_fourcc );
479 int GetOmxChromaFormat( vlc_fourcc_t i_fourcc,
480 OMX_COLOR_FORMATTYPE *pi_omx_codec,
481 const char **ppsz_name )
485 i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc );
487 for( i = 0; chroma_format_table[i].i_codec != 0; i++ )
488 if( chroma_format_table[i].i_fourcc == i_fourcc ) break;
490 if( pi_omx_codec ) *pi_omx_codec = chroma_format_table[i].i_codec;
491 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( VIDEO_ES, i_fourcc );
492 return !!chroma_format_table[i].i_codec;
495 int GetVlcChromaFormat( OMX_COLOR_FORMATTYPE i_omx_codec,
496 vlc_fourcc_t *pi_fourcc, const char **ppsz_name )
500 for( i = 0; chroma_format_table[i].i_codec != 0; i++ )
501 if( chroma_format_table[i].i_codec == i_omx_codec ) break;
503 if( pi_fourcc ) *pi_fourcc = chroma_format_table[i].i_fourcc;
504 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( VIDEO_ES,
505 chroma_format_table[i].i_fourcc );
506 return !!chroma_format_table[i].i_fourcc;
509 int GetVlcChromaSizes( vlc_fourcc_t i_fourcc,
510 unsigned int width, unsigned int height,
511 unsigned int *size, unsigned int *pitch,
512 unsigned int *chroma_pitch_div )
516 i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc );
518 for( i = 0; chroma_format_table[i].i_codec != 0; i++ )
519 if( chroma_format_table[i].i_fourcc == i_fourcc ) break;
521 /* Align on macroblock boundary */
522 width = (width + 15) & ~0xF;
523 height = (height + 15) & ~0xF;
525 if( size ) *size = width * height * chroma_format_table[i].i_size_mul / 2;
526 if( pitch ) *pitch = width * chroma_format_table[i].i_line_mul;
527 if( chroma_pitch_div )
528 *chroma_pitch_div = chroma_format_table[i].i_line_chroma_div;
529 return !!chroma_format_table[i].i_codec;
532 /*****************************************************************************
533 * Functions to deal with audio format parameters
534 *****************************************************************************/
535 static const struct {
536 OMX_AUDIO_CODINGTYPE encoding;
539 } audio_encoding_param[] =
540 { { OMX_AUDIO_CodingPCM, OMX_IndexParamAudioPcm,
541 sizeof(OMX_AUDIO_PARAM_PCMMODETYPE) },
542 { OMX_AUDIO_CodingADPCM, OMX_IndexParamAudioAdpcm,
543 sizeof(OMX_AUDIO_PARAM_ADPCMTYPE) },
544 { OMX_AUDIO_CodingAMR, OMX_IndexParamAudioAmr,
545 sizeof(OMX_AUDIO_PARAM_AMRTYPE) },
546 { OMX_AUDIO_CodingG711, OMX_IndexParamAudioPcm,
547 sizeof(OMX_AUDIO_PARAM_PCMMODETYPE) },
548 { OMX_AUDIO_CodingG723, OMX_IndexParamAudioG723,
549 sizeof(OMX_AUDIO_PARAM_G723TYPE) },
550 { OMX_AUDIO_CodingG726, OMX_IndexParamAudioG726,
551 sizeof(OMX_AUDIO_PARAM_G726TYPE) },
552 { OMX_AUDIO_CodingG729, OMX_IndexParamAudioG729,
553 sizeof(OMX_AUDIO_PARAM_G729TYPE) },
554 { OMX_AUDIO_CodingAAC, OMX_IndexParamAudioAac,
555 sizeof(OMX_AUDIO_PARAM_AACPROFILETYPE) },
556 { OMX_AUDIO_CodingMP3, OMX_IndexParamAudioMp3,
557 sizeof(OMX_AUDIO_PARAM_MP3TYPE) },
558 { OMX_AUDIO_CodingSBC, OMX_IndexParamAudioSbc,
559 sizeof(OMX_AUDIO_PARAM_SBCTYPE) },
560 { OMX_AUDIO_CodingVORBIS, OMX_IndexParamAudioVorbis,
561 sizeof(OMX_AUDIO_PARAM_VORBISTYPE) },
562 { OMX_AUDIO_CodingWMA, OMX_IndexParamAudioWma,
563 sizeof(OMX_AUDIO_PARAM_WMATYPE) },
564 { OMX_AUDIO_CodingRA, OMX_IndexParamAudioRa,
565 sizeof(OMX_AUDIO_PARAM_RATYPE) },
566 { OMX_AUDIO_CodingUnused, 0, 0 }
569 static OMX_INDEXTYPE GetAudioParamFormatIndex(OMX_AUDIO_CODINGTYPE encoding)
573 for(i = 0; audio_encoding_param[i].encoding != OMX_AUDIO_CodingUnused &&
574 audio_encoding_param[i].encoding != encoding; i++);
576 return audio_encoding_param[i].index;
579 unsigned int GetAudioParamSize(OMX_INDEXTYPE index)
583 for(i = 0; audio_encoding_param[i].encoding != OMX_AUDIO_CodingUnused &&
584 audio_encoding_param[i].index != index; i++);
586 return audio_encoding_param[i].size;
589 OMX_ERRORTYPE SetAudioParameters(OMX_HANDLETYPE handle,
590 OmxFormatParam *param, OMX_U32 i_port, OMX_AUDIO_CODINGTYPE encoding,
591 uint8_t i_channels, unsigned int i_samplerate, unsigned int i_bitrate,
592 unsigned int i_bps, unsigned int i_blocksize)
598 case OMX_AUDIO_CodingPCM:
599 case OMX_AUDIO_CodingG711:
600 OMX_INIT_STRUCTURE(param->pcm);
601 param->pcm.nChannels = i_channels;
602 param->pcm.nSamplingRate = i_samplerate;
603 param->pcm.eNumData = OMX_NumericalDataSigned;
604 param->pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
605 param->pcm.eEndian = OMX_EndianLittle;
606 param->pcm.bInterleaved = OMX_TRUE;
607 param->pcm.nBitPerSample = i_bps;
608 param->pcm.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
611 param->pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
612 param->pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
615 case OMX_AUDIO_CodingADPCM:
616 OMX_INIT_STRUCTURE(param->adpcm);
617 param->adpcm.nChannels = i_channels;
618 param->adpcm.nSampleRate = i_samplerate;
619 param->adpcm.nBitsPerSample = i_bps;
621 case OMX_AUDIO_CodingAMR:
622 OMX_INIT_STRUCTURE(param->amr);
623 param->amr.nChannels = i_channels;
624 param->amr.nBitRate = i_bitrate;
625 param->amr.eAMRBandMode = OMX_AUDIO_AMRBandModeUnused;
626 param->amr.eAMRDTXMode = OMX_AUDIO_AMRDTXModeOff;
627 param->amr.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatConformance;
629 case OMX_AUDIO_CodingG723:
630 OMX_INIT_STRUCTURE(param->g723);
631 param->g723.nChannels = i_channels;
632 param->g723.bDTX = OMX_FALSE;
633 param->g723.eBitRate = OMX_AUDIO_G723ModeUnused;
634 param->g723.bHiPassFilter = OMX_TRUE;
635 param->g723.bPostFilter = OMX_TRUE;
637 case OMX_AUDIO_CodingG726:
638 OMX_INIT_STRUCTURE(param->g726);
639 param->g726.nChannels = i_channels;
640 param->g726.eG726Mode = OMX_AUDIO_G726ModeUnused;
642 case OMX_AUDIO_CodingG729:
643 OMX_INIT_STRUCTURE(param->g729);
644 param->g729.nChannels = i_channels;
645 param->g729.bDTX = OMX_FALSE;
646 param->g729.eBitType = OMX_AUDIO_G729;
648 case OMX_AUDIO_CodingAAC:
649 OMX_INIT_STRUCTURE(param->aac);
650 param->aac.nChannels = i_channels;
651 param->aac.nSampleRate = i_samplerate;
652 param->aac.nBitRate = i_bitrate;
653 param->aac.nAudioBandWidth = 0;
654 param->aac.nFrameLength = 1024;
655 param->aac.nAACtools = OMX_AUDIO_AACToolAll;
656 param->aac.nAACERtools = OMX_AUDIO_AACERAll;
657 param->aac.eAACProfile = OMX_AUDIO_AACObjectLC;
658 param->aac.eAACStreamFormat = OMX_AUDIO_AACStreamFormatRAW;
659 param->aac.eChannelMode = i_channels ?
660 OMX_AUDIO_ChannelModeStereo : OMX_AUDIO_ChannelModeMono;
662 case OMX_AUDIO_CodingMP3:
663 OMX_INIT_STRUCTURE(param->mp3);
664 param->mp3.nChannels = i_channels;
665 param->mp3.nSampleRate = i_samplerate;
666 param->mp3.nBitRate = i_bitrate;
667 param->mp3.eChannelMode = i_channels ?
668 OMX_AUDIO_ChannelModeStereo : OMX_AUDIO_ChannelModeMono;
669 param->mp3.eFormat = OMX_AUDIO_MP3StreamFormatMP1Layer3;
671 case OMX_AUDIO_CodingWMA:
672 OMX_INIT_STRUCTURE(param->wma);
673 param->wma.nChannels = i_channels;
674 param->wma.nBitRate = i_bitrate;
675 param->wma.eFormat = OMX_AUDIO_WMAFormatUnused;
676 param->wma.eProfile = OMX_AUDIO_WMAProfileUnused;
677 param->wma.nSamplingRate = i_samplerate;
678 param->wma.nBlockAlign = i_blocksize;
679 param->wma.nEncodeOptions = 0;
680 param->wma.nSuperBlockAlign = 0;
682 case OMX_AUDIO_CodingRA:
683 OMX_INIT_STRUCTURE(param->ra);
684 param->ra.nChannels = i_channels;
685 param->ra.nSamplingRate = i_samplerate;
686 param->ra.nBitsPerFrame = i_bps;
687 param->ra.nSamplePerFrame = 0;
688 param->ra.nCouplingQuantBits = 0;
689 param->ra.nCouplingStartRegion = 0;
690 param->ra.nNumRegions = 0;
691 param->ra.eFormat = OMX_AUDIO_RAFormatUnused;
693 case OMX_AUDIO_CodingVORBIS:
694 OMX_INIT_STRUCTURE(param->vorbis);
695 param->vorbis.nChannels = i_channels;
696 param->vorbis.nBitRate = i_bitrate;
697 param->vorbis.nMinBitRate = 0;
698 param->vorbis.nMaxBitRate = i_bitrate;
699 param->vorbis.nSampleRate = i_samplerate;
700 param->vorbis.nAudioBandWidth = 0;
701 param->vorbis.nQuality = 3;
702 param->vorbis.bManaged = OMX_FALSE;
703 param->vorbis.bDownmix = OMX_FALSE;
706 return OMX_ErrorBadParameter;
709 param->common.nPortIndex = i_port;
711 index = GetAudioParamFormatIndex(encoding);
712 return OMX_SetParameter(handle, index, param);
715 OMX_ERRORTYPE GetAudioParameters(OMX_HANDLETYPE handle,
716 OmxFormatParam *param, OMX_U32 i_port, OMX_AUDIO_CODINGTYPE encoding,
717 uint8_t *pi_channels, unsigned int *pi_samplerate,
718 unsigned int *pi_bitrate, unsigned int *pi_bps, unsigned int *pi_blocksize)
720 int i_channels = 0, i_samplerate = 0, i_bitrate = 0;
721 int i_bps = 0, i_blocksize = 0;
722 OMX_ERRORTYPE omx_error;
725 OMX_INIT_COMMON(param->common);
726 param->common.nPortIndex = i_port;
727 index = GetAudioParamFormatIndex(encoding);
728 if(!index) return OMX_ErrorNotImplemented;
730 param->common.nSize = GetAudioParamSize(index);
731 omx_error = OMX_GetParameter(handle, index, param);
732 if(omx_error != OMX_ErrorNone) return omx_error;
736 case OMX_AUDIO_CodingPCM:
737 case OMX_AUDIO_CodingG711:
738 i_channels = param->pcm.nChannels;
739 i_samplerate = param->pcm.nSamplingRate;
740 i_bps = param->pcm.nBitPerSample;
742 case OMX_AUDIO_CodingADPCM:
743 i_channels = param->adpcm.nChannels;
744 i_samplerate = param->adpcm.nSampleRate;
745 i_bps = param->adpcm.nBitsPerSample;
747 case OMX_AUDIO_CodingAMR:
748 i_channels = param->amr.nChannels;
749 i_bitrate = param->amr.nBitRate;
752 case OMX_AUDIO_CodingG723:
753 i_channels = param->g723.nChannels;
755 case OMX_AUDIO_CodingG726:
756 i_channels = param->g726.nChannels;
758 case OMX_AUDIO_CodingG729:
759 i_channels = param->g729.nChannels;
761 case OMX_AUDIO_CodingAAC:
762 i_channels = param->aac.nChannels;
763 i_samplerate = param->aac.nSampleRate;
764 i_bitrate = param->aac.nBitRate;
765 i_channels = param->aac.eChannelMode == OMX_AUDIO_ChannelModeStereo ? 2 : 1;
767 case OMX_AUDIO_CodingMP3:
768 i_channels = param->mp3.nChannels;
769 i_samplerate = param->mp3.nSampleRate;
770 i_bitrate = param->mp3.nBitRate;
771 i_channels = param->mp3.eChannelMode == OMX_AUDIO_ChannelModeStereo ? 2 : 1;
773 case OMX_AUDIO_CodingVORBIS:
774 i_channels = param->vorbis.nChannels;
775 i_bitrate = param->vorbis.nBitRate;
776 i_samplerate = param->vorbis.nSampleRate;
778 case OMX_AUDIO_CodingWMA:
779 i_channels = param->wma.nChannels;
780 i_bitrate = param->wma.nBitRate;
781 i_samplerate = param->wma.nSamplingRate;
782 i_blocksize = param->wma.nBlockAlign;
784 case OMX_AUDIO_CodingRA:
785 i_channels = param->ra.nChannels;
786 i_samplerate = param->ra.nSamplingRate;
787 i_bps = param->ra.nBitsPerFrame;
790 return OMX_ErrorBadParameter;
793 if(pi_channels) *pi_channels = i_channels;
794 if(pi_samplerate) *pi_samplerate = i_samplerate;
795 if(pi_bitrate) *pi_bitrate = i_bitrate;
796 if(pi_bps) *pi_bps = i_bps;
797 if(pi_blocksize) *pi_blocksize = i_blocksize;
798 return OMX_ErrorNone;
801 /*****************************************************************************
802 * PrintOmx: print component summary
803 *****************************************************************************/
804 void PrintOmx(decoder_t *p_dec, OMX_HANDLETYPE omx_handle, OMX_U32 i_port)
806 OMX_PARAM_PORTDEFINITIONTYPE definition;
807 OMX_PORT_PARAM_TYPE param;
808 OMX_ERRORTYPE omx_error;
811 /* Find the input / output ports */
812 OMX_INIT_STRUCTURE(param);
813 OMX_INIT_STRUCTURE(definition);
815 for(i = 0; i < 3; i++)
817 omx_error = OMX_GetParameter(omx_handle, OMX_IndexParamAudioInit + i, ¶m);
818 if(omx_error != OMX_ErrorNone) continue;
820 if(i_port == OMX_ALL)
821 msg_Dbg( p_dec, "found %i %s ports", (int)param.nPorts,
822 i == 0 ? "audio" : i == 1 ? "image" : "video" );
824 for(j = 0; j < param.nPorts; j++)
826 unsigned int i_samplerate, i_bitrate;
827 unsigned int i_bitspersample, i_blockalign;
829 OmxFormatParam format_param;
830 vlc_fourcc_t i_fourcc;
831 const char *psz_name;
833 if(i_port != OMX_ALL && i_port != param.nStartPortNumber + j)
836 /* Get port definition */
837 definition.nPortIndex = param.nStartPortNumber + j;
838 omx_error = OMX_GetParameter(omx_handle, OMX_IndexParamPortDefinition,
840 if(omx_error != OMX_ErrorNone) continue;
842 OMX_PARAM_U32TYPE u32param;
843 OMX_INIT_STRUCTURE(u32param);
844 u32param.nPortIndex = param.nStartPortNumber + j;
845 omx_error = OMX_GetParameter(omx_handle, OMX_IndexParamNumAvailableStreams,
848 msg_Dbg( p_dec, "-> %s %i (%i streams) (%i:%i:%i buffers) (%i,%i) %s",
849 definition.eDir == OMX_DirOutput ? "output" : "input",
850 (int)definition.nPortIndex, (int)u32param.nU32,
851 (int)definition.nBufferCountActual,
852 (int)definition.nBufferCountMin, (int)definition.nBufferSize,
853 (int)definition.bBuffersContiguous,
854 (int)definition.nBufferAlignment,
855 definition.bEnabled ? "enabled" : "disabled" );
857 switch(definition.eDomain)
859 case OMX_PortDomainVideo:
861 if(definition.format.video.eCompressionFormat)
862 GetVlcVideoFormat( definition.format.video.eCompressionFormat,
863 &i_fourcc, &psz_name );
865 GetVlcChromaFormat( definition.format.video.eColorFormat,
866 &i_fourcc, &psz_name );
868 msg_Dbg( p_dec, " -> video %s %ix%i@%.2f (%i,%i) (%i,%i)", psz_name,
869 (int)definition.format.video.nFrameWidth,
870 (int)definition.format.video.nFrameHeight,
871 (float)definition.format.video.xFramerate/(float)(1<<16),
872 (int)definition.format.video.eCompressionFormat,
873 (int)definition.format.video.eColorFormat,
874 (int)definition.format.video.nStride,
875 (int)definition.format.video.nSliceHeight);
878 case OMX_PortDomainAudio:
880 GetVlcAudioFormat( definition.format.audio.eEncoding,
881 &i_fourcc, &psz_name );
883 GetAudioParameters(omx_handle, &format_param,
884 definition.nPortIndex,
885 definition.format.audio.eEncoding,
886 &i_channels, &i_samplerate, &i_bitrate,
887 &i_bitspersample, &i_blockalign);
889 msg_Dbg( p_dec, " -> audio %s (%i) %i,%i,%i,%i,%i", psz_name,
890 (int)definition.format.audio.eEncoding,
891 i_channels, i_samplerate, i_bitrate, i_bitspersample,