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 #if defined(HAVE_DL_DLOPEN)
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_codec.h>
38 #include <vlc_block_helper.h>
43 /*****************************************************************************
44 * Events utility functions
45 *****************************************************************************/
46 OMX_ERRORTYPE
PostOmxEvent(decoder_t
*p_dec
, OMX_EVENTTYPE event
,
47 OMX_U32 data_1
, OMX_U32 data_2
, OMX_PTR event_data
)
49 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
52 p_event
= malloc(sizeof(OmxEvent
));
53 if(!p_event
) return OMX_ErrorInsufficientResources
;
55 p_event
->event
= event
;
56 p_event
->data_1
= data_1
;
57 p_event
->data_2
= data_2
;
58 p_event
->event_data
= event_data
;
61 vlc_mutex_lock(&p_sys
->mutex
);
62 *p_sys
->pp_last_event
= p_event
;
63 p_sys
->pp_last_event
= &p_event
->next
;
64 vlc_cond_signal(&p_sys
->cond
);
65 vlc_mutex_unlock(&p_sys
->mutex
);
69 OMX_ERRORTYPE
WaitForOmxEvent(decoder_t
*p_dec
, OMX_EVENTTYPE
*event
,
70 OMX_U32
*data_1
, OMX_U32
*data_2
, OMX_PTR
*event_data
)
72 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
75 vlc_mutex_lock(&p_sys
->mutex
);
78 vlc_cond_timedwait(&p_sys
->cond
, &p_sys
->mutex
, mdate()+CLOCK_FREQ
);
80 p_event
= p_sys
->p_events
;
83 p_sys
->p_events
= p_event
->next
;
84 if(!p_sys
->p_events
) p_sys
->pp_last_event
= &p_sys
->p_events
;
87 vlc_mutex_unlock(&p_sys
->mutex
);
91 if(event
) *event
= p_event
->event
;
92 if(data_1
) *data_1
= p_event
->data_1
;
93 if(data_2
) *data_2
= p_event
->data_2
;
94 if(event_data
) *event_data
= p_event
->event_data
;
99 return OMX_ErrorTimeout
;
102 OMX_ERRORTYPE
WaitForSpecificOmxEvent(decoder_t
*p_dec
,
103 OMX_EVENTTYPE specific_event
, OMX_U32
*data_1
, OMX_U32
*data_2
,
106 OMX_ERRORTYPE status
;
108 mtime_t before
= mdate();
112 status
= WaitForOmxEvent(p_dec
, &event
, data_1
, data_2
, event_data
);
113 if(status
!= OMX_ErrorNone
) return status
;
115 if(event
== specific_event
) break;
116 if(mdate() - before
> CLOCK_FREQ
) return OMX_ErrorTimeout
;
119 return OMX_ErrorNone
;
122 /*****************************************************************************
123 * Picture utility functions
124 *****************************************************************************/
125 void CopyOmxPicture( decoder_t
*p_dec
, picture_t
*p_pic
,
126 OMX_BUFFERHEADERTYPE
*p_header
)
128 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
129 int i_src_stride
, i_dst_stride
;
130 int i_plane
, i_width
, i_line
;
131 uint8_t *p_dst
, *p_src
;
133 i_src_stride
= p_sys
->out
.i_frame_stride
;
134 p_src
= p_header
->pBuffer
+ p_header
->nOffset
;
136 for( i_plane
= 0; i_plane
< p_pic
->i_planes
; i_plane
++ )
138 if(i_plane
== 1) i_src_stride
/= p_sys
->out
.i_frame_stride_chroma_div
;
139 p_dst
= p_pic
->p
[i_plane
].p_pixels
;
140 i_dst_stride
= p_pic
->p
[i_plane
].i_pitch
;
141 i_width
= p_pic
->p
[i_plane
].i_visible_pitch
;
143 for( i_line
= 0; i_line
< p_pic
->p
[i_plane
].i_visible_lines
; i_line
++ )
145 vlc_memcpy( p_dst
, p_src
, i_width
);
146 p_src
+= i_src_stride
;
147 p_dst
+= i_dst_stride
;
152 void CopyVlcPicture( decoder_t
*p_dec
, OMX_BUFFERHEADERTYPE
*p_header
,
155 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
156 int i_src_stride
, i_dst_stride
;
157 int i_plane
, i_width
, i_line
;
158 uint8_t *p_dst
, *p_src
;
160 i_dst_stride
= p_sys
->out
.i_frame_stride
;
161 p_dst
= p_header
->pBuffer
+ p_header
->nOffset
;
163 for( i_plane
= 0; i_plane
< p_pic
->i_planes
; i_plane
++ )
165 if(i_plane
== 1) i_dst_stride
/= p_sys
->in
.i_frame_stride_chroma_div
;
166 p_src
= p_pic
->p
[i_plane
].p_pixels
;
167 i_src_stride
= p_pic
->p
[i_plane
].i_pitch
;
168 i_width
= p_pic
->p
[i_plane
].i_visible_pitch
;
170 for( i_line
= 0; i_line
< p_pic
->p
[i_plane
].i_visible_lines
; i_line
++ )
172 vlc_memcpy( p_dst
, p_src
, i_width
);
173 p_src
+= i_src_stride
;
174 p_dst
+= i_dst_stride
;
179 /*****************************************************************************
180 * Logging utility functions
181 *****************************************************************************/
182 const char *StateToString(OMX_STATETYPE state
)
184 static const char *psz_names
[] = {
185 "OMX_StateInvalid", "OMX_StateLoaded", "OMX_StateIdle",
186 "OMX_StateExecuting", "OMX_StatePause", "OMX_StateWaitForResources",
190 if((unsigned int)state
> sizeof(psz_names
)/sizeof(char*)-1)
191 state
= (OMX_STATETYPE
)(sizeof(psz_names
)/sizeof(char*)-1);
192 return psz_names
[state
];
195 const char *CommandToString(OMX_COMMANDTYPE command
)
197 static const char *psz_names
[] = {
198 "OMX_CommandStateSet", "OMX_CommandFlush", "OMX_CommandPortDisable",
199 "OMX_CommandPortEnable", "OMX_CommandMarkBuffer",
200 "OMX_Command unknown"
203 if((unsigned int)command
> sizeof(psz_names
)/sizeof(char*)-1)
204 command
= (OMX_COMMANDTYPE
)(sizeof(psz_names
)/sizeof(char*)-1);
205 return psz_names
[command
];
208 const char *EventToString(OMX_EVENTTYPE event
)
210 static const char *psz_names
[] = {
211 "OMX_EventCmdComplete", "OMX_EventError", "OMX_EventMark",
212 "OMX_EventPortSettingsChanged", "OMX_EventBufferFlag",
213 "OMX_EventResourcesAcquired", "OMX_EventComponentResumed",
214 "OMX_EventDynamicResourcesAvailable", "OMX_EventPortFormatDetected",
218 if((unsigned int)event
> sizeof(psz_names
)/sizeof(char*)-1)
219 event
= (OMX_EVENTTYPE
)(sizeof(psz_names
)/sizeof(char*)-1);
220 return psz_names
[event
];
223 const char *ErrorToString(OMX_ERRORTYPE error
)
225 static const char *psz_names
[] = {
226 "OMX_ErrorInsufficientResources", "OMX_ErrorUndefined",
227 "OMX_ErrorInvalidComponentName", "OMX_ErrorComponentNotFound",
228 "OMX_ErrorInvalidComponent", "OMX_ErrorBadParameter",
229 "OMX_ErrorNotImplemented", "OMX_ErrorUnderflow",
230 "OMX_ErrorOverflow", "OMX_ErrorHardware", "OMX_ErrorInvalidState",
231 "OMX_ErrorStreamCorrupt", "OMX_ErrorPortsNotCompatible",
232 "OMX_ErrorResourcesLost", "OMX_ErrorNoMore", "OMX_ErrorVersionMismatch",
233 "OMX_ErrorNotReady", "OMX_ErrorTimeout", "OMX_ErrorSameState",
234 "OMX_ErrorResourcesPreempted", "OMX_ErrorPortUnresponsiveDuringAllocation",
235 "OMX_ErrorPortUnresponsiveDuringDeallocation",
236 "OMX_ErrorPortUnresponsiveDuringStop", "OMX_ErrorIncorrectStateTransition",
237 "OMX_ErrorIncorrectStateOperation", "OMX_ErrorUnsupportedSetting",
238 "OMX_ErrorUnsupportedIndex", "OMX_ErrorBadPortIndex",
239 "OMX_ErrorPortUnpopulated", "OMX_ErrorComponentSuspended",
240 "OMX_ErrorDynamicResourcesUnavailable", "OMX_ErrorMbErrorsInFrame",
241 "OMX_ErrorFormatNotDetected", "OMX_ErrorContentPipeOpenFailed",
242 "OMX_ErrorContentPipeCreationFailed", "OMX_ErrorSeperateTablesUsed",
243 "OMX_ErrorTunnelingUnsupported",
247 if(error
== OMX_ErrorNone
) return "OMX_ErrorNone";
249 error
-= OMX_ErrorInsufficientResources
;
251 if((unsigned int)error
> sizeof(psz_names
)/sizeof(char*)-1)
252 error
= (OMX_STATETYPE
)(sizeof(psz_names
)/sizeof(char*)-1);
253 return psz_names
[error
];
256 /*****************************************************************************
257 * fourcc -> omx id mapping
258 *****************************************************************************/
261 vlc_fourcc_t i_fourcc
;
262 OMX_VIDEO_CODINGTYPE i_codec
;
263 const char *psz_role
;
265 } video_format_table
[] =
267 { VLC_CODEC_MPGV
, OMX_VIDEO_CodingMPEG2
, "video_decoder.mpeg2" },
268 { VLC_CODEC_MP4V
, OMX_VIDEO_CodingMPEG4
, "video_decoder.mpeg4" },
269 { VLC_CODEC_H264
, OMX_VIDEO_CodingAVC
, "video_decoder.avc" },
270 { VLC_CODEC_H263
, OMX_VIDEO_CodingH263
, "video_decoder.h263" },
271 { VLC_CODEC_WMV1
, OMX_VIDEO_CodingWMV
, "video_decoder.wmv" },
272 { VLC_CODEC_WMV2
, OMX_VIDEO_CodingWMV
, "video_decoder.wmv" },
273 { VLC_CODEC_WMV3
, OMX_VIDEO_CodingWMV
, "video_decoder.wmv" },
274 { VLC_CODEC_MJPG
, OMX_VIDEO_CodingMJPEG
, "video_decoder.jpeg" },
275 { VLC_CODEC_RV10
, OMX_VIDEO_CodingRV
, "video_decoder.rv" },
276 { VLC_CODEC_RV20
, OMX_VIDEO_CodingRV
, "video_decoder.rv" },
277 { VLC_CODEC_RV30
, OMX_VIDEO_CodingRV
, "video_decoder.rv" },
278 { VLC_CODEC_RV40
, OMX_VIDEO_CodingRV
, "video_decoder.rv" },
284 vlc_fourcc_t i_fourcc
;
285 OMX_AUDIO_CODINGTYPE i_codec
;
286 const char *psz_role
;
288 } audio_format_table
[] =
290 { VLC_CODEC_AMR_NB
, OMX_AUDIO_CodingAMR
, "audio_decoder.amr" },
291 { VLC_CODEC_AMR_WB
, OMX_AUDIO_CodingAMR
, "audio_decoder.amr" },
292 { VLC_CODEC_MP4A
, OMX_AUDIO_CodingAAC
, "audio_decoder.aac" },
293 { VLC_CODEC_S16N
, OMX_AUDIO_CodingPCM
, "audio_decoder.pcm" },
299 vlc_fourcc_t i_fourcc
;
300 OMX_VIDEO_CODINGTYPE i_codec
;
301 const char *psz_role
;
303 } video_enc_format_table
[] =
305 { VLC_CODEC_MPGV
, OMX_VIDEO_CodingMPEG2
, "video_encoder.mpeg2" },
306 { VLC_CODEC_MP4V
, OMX_VIDEO_CodingMPEG4
, "video_encoder.mpeg4" },
307 { VLC_CODEC_H264
, OMX_VIDEO_CodingAVC
, "video_encoder.avc" },
308 { VLC_CODEC_H263
, OMX_VIDEO_CodingH263
, "video_encoder.h263" },
309 { VLC_CODEC_WMV1
, OMX_VIDEO_CodingWMV
, "video_encoder.wmv" },
310 { VLC_CODEC_WMV2
, OMX_VIDEO_CodingWMV
, "video_encoder.wmv" },
311 { VLC_CODEC_WMV3
, OMX_VIDEO_CodingWMV
, "video_encoder.wmv" },
312 { VLC_CODEC_MJPG
, OMX_VIDEO_CodingMJPEG
, "video_encoder.jpeg" },
313 { VLC_CODEC_RV10
, OMX_VIDEO_CodingRV
, "video_encoder.rv" },
314 { VLC_CODEC_RV20
, OMX_VIDEO_CodingRV
, "video_encoder.rv" },
315 { VLC_CODEC_RV30
, OMX_VIDEO_CodingRV
, "video_encoder.rv" },
316 { VLC_CODEC_RV40
, OMX_VIDEO_CodingRV
, "video_encoder.rv" },
322 vlc_fourcc_t i_fourcc
;
323 OMX_AUDIO_CODINGTYPE i_codec
;
324 const char *psz_role
;
326 } audio_enc_format_table
[] =
328 { VLC_CODEC_AMR_NB
, OMX_AUDIO_CodingAMR
, "audio_encoder.amr" },
329 { VLC_CODEC_AMR_WB
, OMX_AUDIO_CodingAMR
, "audio_encoder.amr" },
330 { VLC_CODEC_MP4A
, OMX_AUDIO_CodingAAC
, "audio_encoder.aac" },
331 { VLC_CODEC_S16N
, OMX_AUDIO_CodingPCM
, "audio_encoder.pcm" },
337 vlc_fourcc_t i_fourcc
;
338 OMX_COLOR_FORMATTYPE i_codec
;
339 unsigned int i_size_mul
;
340 unsigned int i_line_mul
;
341 unsigned int i_line_chroma_div
;
343 } chroma_format_table
[] =
345 { VLC_CODEC_I420
, OMX_COLOR_FormatYUV420Planar
, 3, 1, 2 },
346 { VLC_CODEC_I420
, OMX_COLOR_FormatYUV420PackedPlanar
, 3, 1, 2 },
347 { VLC_CODEC_YUYV
, OMX_COLOR_FormatYCbYCr
, 4, 2, 0 },
348 { VLC_CODEC_YVYU
, OMX_COLOR_FormatYCrYCb
, 4, 2, 0 },
349 { VLC_CODEC_UYVY
, OMX_COLOR_FormatCbYCrY
, 4, 2, 0 },
350 { VLC_CODEC_VYUY
, OMX_COLOR_FormatCrYCbY
, 4, 2, 0 },
354 int GetOmxVideoFormat( vlc_fourcc_t i_fourcc
,
355 OMX_VIDEO_CODINGTYPE
*pi_omx_codec
,
356 const char **ppsz_name
)
360 i_fourcc
= vlc_fourcc_GetCodec( VIDEO_ES
, i_fourcc
);
362 for( i
= 0; video_format_table
[i
].i_codec
!= 0; i
++ )
363 if( video_format_table
[i
].i_fourcc
== i_fourcc
) break;
365 if( pi_omx_codec
) *pi_omx_codec
= video_format_table
[i
].i_codec
;
366 if( ppsz_name
) *ppsz_name
= vlc_fourcc_GetDescription( VIDEO_ES
, i_fourcc
);
367 return !!video_format_table
[i
].i_codec
;
370 int GetVlcVideoFormat( OMX_VIDEO_CODINGTYPE i_omx_codec
,
371 vlc_fourcc_t
*pi_fourcc
, const char **ppsz_name
)
375 for( i
= 0; video_format_table
[i
].i_codec
!= 0; i
++ )
376 if( video_format_table
[i
].i_codec
== i_omx_codec
) break;
378 if( pi_fourcc
) *pi_fourcc
= video_format_table
[i
].i_fourcc
;
379 if( ppsz_name
) *ppsz_name
= vlc_fourcc_GetDescription( VIDEO_ES
,
380 video_format_table
[i
].i_fourcc
);
381 return !!video_format_table
[i
].i_fourcc
;
384 static const char *GetOmxVideoRole( vlc_fourcc_t i_fourcc
)
388 i_fourcc
= vlc_fourcc_GetCodec( VIDEO_ES
, i_fourcc
);
390 for( i
= 0; video_format_table
[i
].i_codec
!= 0; i
++ )
391 if( video_format_table
[i
].i_fourcc
== i_fourcc
) break;
393 return video_format_table
[i
].psz_role
;
396 static const char *GetOmxVideoEncRole( vlc_fourcc_t i_fourcc
)
400 i_fourcc
= vlc_fourcc_GetCodec( VIDEO_ES
, i_fourcc
);
402 for( i
= 0; video_enc_format_table
[i
].i_codec
!= 0; i
++ )
403 if( video_enc_format_table
[i
].i_fourcc
== i_fourcc
) break;
405 return video_enc_format_table
[i
].psz_role
;
408 int GetOmxAudioFormat( vlc_fourcc_t i_fourcc
,
409 OMX_AUDIO_CODINGTYPE
*pi_omx_codec
,
410 const char **ppsz_name
)
414 i_fourcc
= vlc_fourcc_GetCodec( AUDIO_ES
, i_fourcc
);
416 for( i
= 0; audio_format_table
[i
].i_codec
!= 0; i
++ )
417 if( audio_format_table
[i
].i_fourcc
== i_fourcc
) break;
419 if( pi_omx_codec
) *pi_omx_codec
= audio_format_table
[i
].i_codec
;
420 if( ppsz_name
) *ppsz_name
= vlc_fourcc_GetDescription( AUDIO_ES
, i_fourcc
);
421 return !!audio_format_table
[i
].i_codec
;
424 int GetVlcAudioFormat( OMX_AUDIO_CODINGTYPE i_omx_codec
,
425 vlc_fourcc_t
*pi_fourcc
, const char **ppsz_name
)
429 for( i
= 0; audio_format_table
[i
].i_codec
!= 0; i
++ )
430 if( audio_format_table
[i
].i_codec
== i_omx_codec
) break;
432 if( pi_fourcc
) *pi_fourcc
= audio_format_table
[i
].i_fourcc
;
433 if( ppsz_name
) *ppsz_name
= vlc_fourcc_GetDescription( AUDIO_ES
,
434 audio_format_table
[i
].i_fourcc
);
435 return !!audio_format_table
[i
].i_fourcc
;
438 static const char *GetOmxAudioRole( vlc_fourcc_t i_fourcc
)
442 i_fourcc
= vlc_fourcc_GetCodec( AUDIO_ES
, i_fourcc
);
444 for( i
= 0; audio_format_table
[i
].i_codec
!= 0; i
++ )
445 if( audio_format_table
[i
].i_fourcc
== i_fourcc
) break;
447 return audio_format_table
[i
].psz_role
;
450 static const char *GetOmxAudioEncRole( vlc_fourcc_t i_fourcc
)
454 i_fourcc
= vlc_fourcc_GetCodec( AUDIO_ES
, i_fourcc
);
456 for( i
= 0; audio_enc_format_table
[i
].i_codec
!= 0; i
++ )
457 if( audio_enc_format_table
[i
].i_fourcc
== i_fourcc
) break;
459 return audio_enc_format_table
[i
].psz_role
;
462 const char *GetOmxRole( vlc_fourcc_t i_fourcc
, int i_cat
, bool b_enc
)
465 return i_cat
== VIDEO_ES
?
466 GetOmxVideoEncRole( i_fourcc
) : GetOmxAudioEncRole( i_fourcc
);
468 return i_cat
== VIDEO_ES
?
469 GetOmxVideoRole( i_fourcc
) : GetOmxAudioRole( i_fourcc
);
472 int GetOmxChromaFormat( vlc_fourcc_t i_fourcc
,
473 OMX_COLOR_FORMATTYPE
*pi_omx_codec
,
474 const char **ppsz_name
)
478 i_fourcc
= vlc_fourcc_GetCodec( VIDEO_ES
, i_fourcc
);
480 for( i
= 0; chroma_format_table
[i
].i_codec
!= 0; i
++ )
481 if( chroma_format_table
[i
].i_fourcc
== i_fourcc
) break;
483 if( pi_omx_codec
) *pi_omx_codec
= chroma_format_table
[i
].i_codec
;
484 if( ppsz_name
) *ppsz_name
= vlc_fourcc_GetDescription( VIDEO_ES
, i_fourcc
);
485 return !!chroma_format_table
[i
].i_codec
;
488 int GetVlcChromaFormat( OMX_COLOR_FORMATTYPE i_omx_codec
,
489 vlc_fourcc_t
*pi_fourcc
, const char **ppsz_name
)
493 for( i
= 0; chroma_format_table
[i
].i_codec
!= 0; i
++ )
494 if( chroma_format_table
[i
].i_codec
== i_omx_codec
) break;
496 if( pi_fourcc
) *pi_fourcc
= chroma_format_table
[i
].i_fourcc
;
497 if( ppsz_name
) *ppsz_name
= vlc_fourcc_GetDescription( VIDEO_ES
,
498 chroma_format_table
[i
].i_fourcc
);
499 return !!chroma_format_table
[i
].i_fourcc
;
502 int GetVlcChromaSizes( vlc_fourcc_t i_fourcc
,
503 unsigned int width
, unsigned int height
,
504 unsigned int *size
, unsigned int *pitch
,
505 unsigned int *chroma_pitch_div
)
509 i_fourcc
= vlc_fourcc_GetCodec( VIDEO_ES
, i_fourcc
);
511 for( i
= 0; chroma_format_table
[i
].i_codec
!= 0; i
++ )
512 if( chroma_format_table
[i
].i_fourcc
== i_fourcc
) break;
514 /* Align on macroblock boundary */
515 width
= (width
+ 15) & ~0xF;
516 height
= (height
+ 15) & ~0xF;
518 if( size
) *size
= width
* height
* chroma_format_table
[i
].i_size_mul
/ 2;
519 if( pitch
) *pitch
= width
* chroma_format_table
[i
].i_line_mul
;
520 if( chroma_pitch_div
)
521 *chroma_pitch_div
= chroma_format_table
[i
].i_line_chroma_div
;
522 return !!chroma_format_table
[i
].i_codec
;
525 /*****************************************************************************
526 * Functions to deal with audio format parameters
527 *****************************************************************************/
528 static const struct {
529 OMX_AUDIO_CODINGTYPE encoding
;
532 } audio_encoding_param
[] =
533 { { OMX_AUDIO_CodingPCM
, OMX_IndexParamAudioPcm
,
534 sizeof(OMX_AUDIO_PARAM_PCMMODETYPE
) },
535 { OMX_AUDIO_CodingADPCM
, OMX_IndexParamAudioAdpcm
,
536 sizeof(OMX_AUDIO_PARAM_ADPCMTYPE
) },
537 { OMX_AUDIO_CodingAMR
, OMX_IndexParamAudioAmr
,
538 sizeof(OMX_AUDIO_PARAM_AMRTYPE
) },
539 { OMX_AUDIO_CodingG711
, OMX_IndexParamAudioPcm
,
540 sizeof(OMX_AUDIO_PARAM_PCMMODETYPE
) },
541 { OMX_AUDIO_CodingG723
, OMX_IndexParamAudioG723
,
542 sizeof(OMX_AUDIO_PARAM_G723TYPE
) },
543 { OMX_AUDIO_CodingG726
, OMX_IndexParamAudioG726
,
544 sizeof(OMX_AUDIO_PARAM_G726TYPE
) },
545 { OMX_AUDIO_CodingG729
, OMX_IndexParamAudioG729
,
546 sizeof(OMX_AUDIO_PARAM_G729TYPE
) },
547 { OMX_AUDIO_CodingAAC
, OMX_IndexParamAudioAac
,
548 sizeof(OMX_AUDIO_PARAM_AACPROFILETYPE
) },
549 { OMX_AUDIO_CodingMP3
, OMX_IndexParamAudioMp3
,
550 sizeof(OMX_AUDIO_PARAM_MP3TYPE
) },
551 { OMX_AUDIO_CodingSBC
, OMX_IndexParamAudioSbc
,
552 sizeof(OMX_AUDIO_PARAM_SBCTYPE
) },
553 { OMX_AUDIO_CodingVORBIS
, OMX_IndexParamAudioVorbis
,
554 sizeof(OMX_AUDIO_PARAM_VORBISTYPE
) },
555 { OMX_AUDIO_CodingWMA
, OMX_IndexParamAudioWma
,
556 sizeof(OMX_AUDIO_PARAM_WMATYPE
) },
557 { OMX_AUDIO_CodingRA
, OMX_IndexParamAudioRa
,
558 sizeof(OMX_AUDIO_PARAM_RATYPE
) },
559 { OMX_AUDIO_CodingUnused
, 0, 0 }
562 static OMX_INDEXTYPE
GetAudioParamFormatIndex(OMX_AUDIO_CODINGTYPE encoding
)
566 for(i
= 0; audio_encoding_param
[i
].encoding
!= OMX_AUDIO_CodingUnused
&&
567 audio_encoding_param
[i
].encoding
!= encoding
; i
++);
569 return audio_encoding_param
[i
].index
;
572 static unsigned int GetAudioParamSize(OMX_INDEXTYPE index
)
576 for(i
= 0; audio_encoding_param
[i
].encoding
!= OMX_AUDIO_CodingUnused
&&
577 audio_encoding_param
[i
].index
!= index
; i
++);
579 return audio_encoding_param
[i
].size
;
582 OMX_ERRORTYPE
SetAudioParameters(OMX_HANDLETYPE handle
,
583 OmxFormatParam
*param
, OMX_U32 i_port
, OMX_AUDIO_CODINGTYPE encoding
,
584 uint8_t i_channels
, unsigned int i_samplerate
, unsigned int i_bitrate
,
585 unsigned int i_bps
, unsigned int i_blocksize
)
591 case OMX_AUDIO_CodingPCM
:
592 case OMX_AUDIO_CodingG711
:
593 OMX_INIT_STRUCTURE(param
->pcm
);
594 param
->pcm
.nChannels
= i_channels
;
595 param
->pcm
.nSamplingRate
= i_samplerate
;
596 param
->pcm
.eNumData
= OMX_NumericalDataSigned
;
597 param
->pcm
.ePCMMode
= OMX_AUDIO_PCMModeLinear
;
598 param
->pcm
.eEndian
= OMX_EndianLittle
;
599 param
->pcm
.bInterleaved
= OMX_TRUE
;
600 param
->pcm
.nBitPerSample
= i_bps
;
601 param
->pcm
.eChannelMapping
[0] = OMX_AUDIO_ChannelCF
;
604 param
->pcm
.eChannelMapping
[0] = OMX_AUDIO_ChannelLF
;
605 param
->pcm
.eChannelMapping
[1] = OMX_AUDIO_ChannelRF
;
608 case OMX_AUDIO_CodingADPCM
:
609 OMX_INIT_STRUCTURE(param
->adpcm
);
610 param
->adpcm
.nChannels
= i_channels
;
611 param
->adpcm
.nSampleRate
= i_samplerate
;
612 param
->adpcm
.nBitsPerSample
= i_bps
;
614 case OMX_AUDIO_CodingAMR
:
615 OMX_INIT_STRUCTURE(param
->amr
);
616 param
->amr
.nChannels
= i_channels
;
617 param
->amr
.nBitRate
= i_bitrate
;
618 param
->amr
.eAMRBandMode
= OMX_AUDIO_AMRBandModeUnused
;
619 param
->amr
.eAMRDTXMode
= OMX_AUDIO_AMRDTXModeOff
;
620 param
->amr
.eAMRFrameFormat
= OMX_AUDIO_AMRFrameFormatConformance
;
622 case OMX_AUDIO_CodingG723
:
623 OMX_INIT_STRUCTURE(param
->g723
);
624 param
->g723
.nChannels
= i_channels
;
625 param
->g723
.bDTX
= OMX_FALSE
;
626 param
->g723
.eBitRate
= OMX_AUDIO_G723ModeUnused
;
627 param
->g723
.bHiPassFilter
= OMX_TRUE
;
628 param
->g723
.bPostFilter
= OMX_TRUE
;
630 case OMX_AUDIO_CodingG726
:
631 OMX_INIT_STRUCTURE(param
->g726
);
632 param
->g726
.nChannels
= i_channels
;
633 param
->g726
.eG726Mode
= OMX_AUDIO_G726ModeUnused
;
635 case OMX_AUDIO_CodingG729
:
636 OMX_INIT_STRUCTURE(param
->g729
);
637 param
->g729
.nChannels
= i_channels
;
638 param
->g729
.bDTX
= OMX_FALSE
;
639 param
->g729
.eBitType
= OMX_AUDIO_G729
;
641 case OMX_AUDIO_CodingAAC
:
642 OMX_INIT_STRUCTURE(param
->aac
);
643 param
->aac
.nChannels
= i_channels
;
644 param
->aac
.nSampleRate
= i_samplerate
;
645 param
->aac
.nBitRate
= i_bitrate
;
646 param
->aac
.nAudioBandWidth
= 0;
647 param
->aac
.nFrameLength
= 1024;
648 param
->aac
.nAACtools
= OMX_AUDIO_AACToolAll
;
649 param
->aac
.nAACERtools
= OMX_AUDIO_AACERAll
;
650 param
->aac
.eAACProfile
= OMX_AUDIO_AACObjectLC
;
651 param
->aac
.eAACStreamFormat
= OMX_AUDIO_AACStreamFormatRAW
;
652 param
->aac
.eChannelMode
= i_channels
?
653 OMX_AUDIO_ChannelModeStereo
: OMX_AUDIO_ChannelModeMono
;
655 case OMX_AUDIO_CodingMP3
:
656 OMX_INIT_STRUCTURE(param
->mp3
);
657 param
->mp3
.nChannels
= i_channels
;
658 param
->mp3
.nSampleRate
= i_samplerate
;
659 param
->mp3
.nBitRate
= i_bitrate
;
660 param
->mp3
.eChannelMode
= i_channels
?
661 OMX_AUDIO_ChannelModeStereo
: OMX_AUDIO_ChannelModeMono
;
662 param
->mp3
.eFormat
= OMX_AUDIO_MP3StreamFormatMP1Layer3
;
664 case OMX_AUDIO_CodingWMA
:
665 OMX_INIT_STRUCTURE(param
->wma
);
666 param
->wma
.nChannels
= i_channels
;
667 param
->wma
.nBitRate
= i_bitrate
;
668 param
->wma
.eFormat
= OMX_AUDIO_WMAFormatUnused
;
669 param
->wma
.eProfile
= OMX_AUDIO_WMAProfileUnused
;
670 param
->wma
.nSamplingRate
= i_samplerate
;
671 param
->wma
.nBlockAlign
= i_blocksize
;
672 param
->wma
.nEncodeOptions
= 0;
673 param
->wma
.nSuperBlockAlign
= 0;
675 case OMX_AUDIO_CodingRA
:
676 OMX_INIT_STRUCTURE(param
->ra
);
677 param
->ra
.nChannels
= i_channels
;
678 param
->ra
.nSamplingRate
= i_samplerate
;
679 param
->ra
.nBitsPerFrame
= i_bps
;
680 param
->ra
.nSamplePerFrame
= 0;
681 param
->ra
.nCouplingQuantBits
= 0;
682 param
->ra
.nCouplingStartRegion
= 0;
683 param
->ra
.nNumRegions
= 0;
684 param
->ra
.eFormat
= OMX_AUDIO_RAFormatUnused
;
686 case OMX_AUDIO_CodingVORBIS
:
687 OMX_INIT_STRUCTURE(param
->vorbis
);
688 param
->vorbis
.nChannels
= i_channels
;
689 param
->vorbis
.nBitRate
= i_bitrate
;
690 param
->vorbis
.nMinBitRate
= 0;
691 param
->vorbis
.nMaxBitRate
= i_bitrate
;
692 param
->vorbis
.nSampleRate
= i_samplerate
;
693 param
->vorbis
.nAudioBandWidth
= 0;
694 param
->vorbis
.nQuality
= 3;
695 param
->vorbis
.bManaged
= OMX_FALSE
;
696 param
->vorbis
.bDownmix
= OMX_FALSE
;
699 return OMX_ErrorBadParameter
;
702 param
->common
.nPortIndex
= i_port
;
704 index
= GetAudioParamFormatIndex(encoding
);
705 return OMX_SetParameter(handle
, index
, param
);
708 OMX_ERRORTYPE
GetAudioParameters(OMX_HANDLETYPE handle
,
709 OmxFormatParam
*param
, OMX_U32 i_port
, OMX_AUDIO_CODINGTYPE encoding
,
710 uint8_t *pi_channels
, unsigned int *pi_samplerate
,
711 unsigned int *pi_bitrate
, unsigned int *pi_bps
, unsigned int *pi_blocksize
)
713 int i_channels
= 0, i_samplerate
= 0, i_bitrate
= 0;
714 int i_bps
= 0, i_blocksize
= 0;
715 OMX_ERRORTYPE omx_error
;
718 OMX_INIT_COMMON(param
->common
);
719 param
->common
.nPortIndex
= i_port
;
720 index
= GetAudioParamFormatIndex(encoding
);
721 if(!index
) return OMX_ErrorNotImplemented
;
723 param
->common
.nSize
= GetAudioParamSize(index
);
724 omx_error
= OMX_GetParameter(handle
, index
, param
);
725 if(omx_error
!= OMX_ErrorNone
) return omx_error
;
729 case OMX_AUDIO_CodingPCM
:
730 case OMX_AUDIO_CodingG711
:
731 i_channels
= param
->pcm
.nChannels
;
732 i_samplerate
= param
->pcm
.nSamplingRate
;
733 i_bps
= param
->pcm
.nBitPerSample
;
735 case OMX_AUDIO_CodingADPCM
:
736 i_channels
= param
->adpcm
.nChannels
;
737 i_samplerate
= param
->adpcm
.nSampleRate
;
738 i_bps
= param
->adpcm
.nBitsPerSample
;
740 case OMX_AUDIO_CodingAMR
:
741 i_channels
= param
->amr
.nChannels
;
742 i_bitrate
= param
->amr
.nBitRate
;
745 case OMX_AUDIO_CodingG723
:
746 i_channels
= param
->g723
.nChannels
;
748 case OMX_AUDIO_CodingG726
:
749 i_channels
= param
->g726
.nChannels
;
751 case OMX_AUDIO_CodingG729
:
752 i_channels
= param
->g729
.nChannels
;
754 case OMX_AUDIO_CodingAAC
:
755 i_channels
= param
->aac
.nChannels
;
756 i_samplerate
= param
->aac
.nSampleRate
;
757 i_bitrate
= param
->aac
.nBitRate
;
758 i_channels
= param
->aac
.eChannelMode
== OMX_AUDIO_ChannelModeStereo
? 2 : 1;
760 case OMX_AUDIO_CodingMP3
:
761 i_channels
= param
->mp3
.nChannels
;
762 i_samplerate
= param
->mp3
.nSampleRate
;
763 i_bitrate
= param
->mp3
.nBitRate
;
764 i_channels
= param
->mp3
.eChannelMode
== OMX_AUDIO_ChannelModeStereo
? 2 : 1;
766 case OMX_AUDIO_CodingVORBIS
:
767 i_channels
= param
->vorbis
.nChannels
;
768 i_bitrate
= param
->vorbis
.nBitRate
;
769 i_samplerate
= param
->vorbis
.nSampleRate
;
771 case OMX_AUDIO_CodingWMA
:
772 i_channels
= param
->wma
.nChannels
;
773 i_bitrate
= param
->wma
.nBitRate
;
774 i_samplerate
= param
->wma
.nSamplingRate
;
775 i_blocksize
= param
->wma
.nBlockAlign
;
777 case OMX_AUDIO_CodingRA
:
778 i_channels
= param
->ra
.nChannels
;
779 i_samplerate
= param
->ra
.nSamplingRate
;
780 i_bps
= param
->ra
.nBitsPerFrame
;
783 return OMX_ErrorBadParameter
;
786 if(pi_channels
) *pi_channels
= i_channels
;
787 if(pi_samplerate
) *pi_samplerate
= i_samplerate
;
788 if(pi_bitrate
) *pi_bitrate
= i_bitrate
;
789 if(pi_bps
) *pi_bps
= i_bps
;
790 if(pi_blocksize
) *pi_blocksize
= i_blocksize
;
791 return OMX_ErrorNone
;
794 /*****************************************************************************
795 * PrintOmx: print component summary
796 *****************************************************************************/
797 void PrintOmx(decoder_t
*p_dec
, OMX_HANDLETYPE omx_handle
, OMX_U32 i_port
)
799 OMX_PARAM_PORTDEFINITIONTYPE definition
;
800 OMX_PORT_PARAM_TYPE param
;
801 OMX_ERRORTYPE omx_error
;
804 /* Find the input / output ports */
805 OMX_INIT_STRUCTURE(param
);
806 OMX_INIT_STRUCTURE(definition
);
808 for(i
= 0; i
< 3; i
++)
810 omx_error
= OMX_GetParameter(omx_handle
, OMX_IndexParamAudioInit
+ i
, ¶m
);
811 if(omx_error
!= OMX_ErrorNone
) continue;
813 if(i_port
== OMX_ALL
)
814 msg_Dbg( p_dec
, "found %i %s ports", (int)param
.nPorts
,
815 i
== 0 ? "audio" : i
== 1 ? "image" : "video" );
817 for(j
= 0; j
< param
.nPorts
; j
++)
819 unsigned int i_samplerate
, i_bitrate
;
820 unsigned int i_bitspersample
, i_blockalign
;
822 OmxFormatParam format_param
;
823 vlc_fourcc_t i_fourcc
;
824 const char *psz_name
;
826 if(i_port
!= OMX_ALL
&& i_port
!= param
.nStartPortNumber
+ j
)
829 /* Get port definition */
830 definition
.nPortIndex
= param
.nStartPortNumber
+ j
;
831 omx_error
= OMX_GetParameter(omx_handle
, OMX_IndexParamPortDefinition
,
833 if(omx_error
!= OMX_ErrorNone
) continue;
835 OMX_PARAM_U32TYPE u32param
;
836 OMX_INIT_STRUCTURE(u32param
);
837 u32param
.nPortIndex
= param
.nStartPortNumber
+ j
;
838 omx_error
= OMX_GetParameter(omx_handle
, OMX_IndexParamNumAvailableStreams
,
841 msg_Dbg( p_dec
, "-> %s %i (%i streams) (%i:%i:%i buffers) (%i,%i) %s",
842 definition
.eDir
== OMX_DirOutput
? "output" : "input",
843 (int)definition
.nPortIndex
, (int)u32param
.nU32
,
844 (int)definition
.nBufferCountActual
,
845 (int)definition
.nBufferCountMin
, (int)definition
.nBufferSize
,
846 (int)definition
.bBuffersContiguous
,
847 (int)definition
.nBufferAlignment
,
848 definition
.bEnabled
? "enabled" : "disabled" );
850 switch(definition
.eDomain
)
852 case OMX_PortDomainVideo
:
854 if(definition
.format
.video
.eCompressionFormat
)
855 GetVlcVideoFormat( definition
.format
.video
.eCompressionFormat
,
856 &i_fourcc
, &psz_name
);
858 GetVlcChromaFormat( definition
.format
.video
.eColorFormat
,
859 &i_fourcc
, &psz_name
);
861 msg_Dbg( p_dec
, " -> video %s %ix%i@%.2f (%i,%i) (%i,%i)", psz_name
,
862 (int)definition
.format
.video
.nFrameWidth
,
863 (int)definition
.format
.video
.nFrameHeight
,
864 (float)definition
.format
.video
.xFramerate
/(float)(1<<16),
865 (int)definition
.format
.video
.eCompressionFormat
,
866 (int)definition
.format
.video
.eColorFormat
,
867 (int)definition
.format
.video
.nStride
,
868 (int)definition
.format
.video
.nSliceHeight
);
871 case OMX_PortDomainAudio
:
873 GetVlcAudioFormat( definition
.format
.audio
.eEncoding
,
874 &i_fourcc
, &psz_name
);
876 GetAudioParameters(omx_handle
, &format_param
,
877 definition
.nPortIndex
,
878 definition
.format
.audio
.eEncoding
,
879 &i_channels
, &i_samplerate
, &i_bitrate
,
880 &i_bitspersample
, &i_blockalign
);
882 msg_Dbg( p_dec
, " -> audio %s (%i) %i,%i,%i,%i,%i", psz_name
,
883 (int)definition
.format
.audio
.eEncoding
,
884 i_channels
, i_samplerate
, i_bitrate
, i_bitspersample
,