omxil: Factorize event debug printing to a separate function
[vlc.git] / modules / codec / omxil / utils.c
blob1521e6b51a2dc36fd59eea6737f86e4b62454a7a
1 /*****************************************************************************
2 * utils.c: helper functions
3 *****************************************************************************
4 * Copyright (C) 2010 VLC authors and VideoLAN
5 * $Id$
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 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_codec.h>
34 #include <vlc_block_helper.h>
35 #include <vlc_cpu.h>
37 #include "omxil.h"
38 #include "qcom.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;
47 OmxEvent *p_event;
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;
56 p_event->next = 0;
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);
63 return OMX_ErrorNone;
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;
70 OmxEvent *p_event;
72 vlc_mutex_lock(&p_sys->mutex);
74 if(!p_sys->p_events)
75 vlc_cond_timedwait(&p_sys->cond, &p_sys->mutex, mdate()+CLOCK_FREQ);
77 p_event = p_sys->p_events;
78 if(p_event)
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);
86 if(p_event)
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;
92 free(p_event);
93 return OMX_ErrorNone;
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,
101 OMX_PTR *event_data)
103 OMX_ERRORTYPE status;
104 OMX_EVENTTYPE event;
105 mtime_t before = mdate();
107 while(1)
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 void PrintOmxEvent(vlc_object_t *p_this, OMX_EVENTTYPE event, OMX_U32 data_1,
120 OMX_U32 data_2, OMX_PTR event_data)
122 switch (event)
124 case OMX_EventCmdComplete:
125 switch ((OMX_STATETYPE)data_1)
127 case OMX_CommandStateSet:
128 msg_Dbg( p_this, "OmxEventHandler (%s, %s, %s)", EventToString(event),
129 CommandToString(data_1), StateToString(data_2) );
130 break;
132 default:
133 msg_Dbg( p_this, "OmxEventHandler (%s, %s, %u)", EventToString(event),
134 CommandToString(data_1), (unsigned int)data_2 );
135 break;
137 break;
139 case OMX_EventError:
140 msg_Dbg( p_this, "OmxEventHandler (%s, %s, %u, %s)", EventToString(event),
141 ErrorToString((OMX_ERRORTYPE)data_1), (unsigned int)data_2,
142 (const char *)event_data);
143 break;
145 default:
146 msg_Dbg( p_this, "OmxEventHandler (%s, %u, %u)", EventToString(event),
147 (unsigned int)data_1, (unsigned int)data_2 );
148 break;
152 /*****************************************************************************
153 * Picture utility functions
154 *****************************************************************************/
155 void CopyOmxPicture( int i_color_format, picture_t *p_pic,
156 int i_slice_height,
157 int i_src_stride, uint8_t *p_src, int i_chroma_div )
159 uint8_t *p_dst;
160 int i_dst_stride;
161 int i_plane, i_width, i_line;
162 if( i_color_format == QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka )
164 qcom_convert(p_src, p_pic);
165 return;
168 for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
170 if(i_plane == 1) i_src_stride /= i_chroma_div;
171 p_dst = p_pic->p[i_plane].p_pixels;
172 i_dst_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 memcpy( p_dst, p_src, i_width );
178 p_src += i_src_stride;
179 p_dst += i_dst_stride;
181 /* Handle plane height, which may be indicated via nSliceHeight in OMX.
182 * The handling for chroma planes currently assumes vertically
183 * subsampled chroma, e.g. 422 planar wouldn't work right. */
184 if( i_plane == 0 && i_slice_height > p_pic->p[i_plane].i_visible_lines )
185 p_src += i_src_stride * (i_slice_height - p_pic->p[i_plane].i_visible_lines);
186 else if ( i_plane > 0 && i_slice_height/2 > p_pic->p[i_plane].i_visible_lines )
187 p_src += i_src_stride * (i_slice_height/2 - p_pic->p[i_plane].i_visible_lines);
191 void CopyVlcPicture( decoder_t *p_dec, OMX_BUFFERHEADERTYPE *p_header,
192 picture_t *p_pic)
194 decoder_sys_t *p_sys = p_dec->p_sys;
195 int i_src_stride, i_dst_stride;
196 int i_plane, i_width, i_line;
197 uint8_t *p_dst, *p_src;
199 i_dst_stride = p_sys->out.i_frame_stride;
200 p_dst = p_header->pBuffer + p_header->nOffset;
202 for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
204 if(i_plane == 1) i_dst_stride /= p_sys->in.i_frame_stride_chroma_div;
205 p_src = p_pic->p[i_plane].p_pixels;
206 i_src_stride = p_pic->p[i_plane].i_pitch;
207 i_width = p_pic->p[i_plane].i_visible_pitch;
209 for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines; i_line++ )
211 memcpy( p_dst, p_src, i_width );
212 p_src += i_src_stride;
213 p_dst += i_dst_stride;
218 int IgnoreOmxDecoderPadding(const char *name)
220 // The list of decoders that signal padding properly is not necessary,
221 // since that is the default, but keep it here for reference. (This is
222 // only relevant for manufacturers that are known to have decoders with
223 // this kind of bug.)
225 static const char *padding_decoders[] = {
226 "OMX.SEC.AVC.Decoder",
227 "OMX.SEC.wmv7.dec",
228 "OMX.SEC.wmv8.dec",
229 NULL
232 static const char *nopadding_decoders[] = {
233 "OMX.SEC.avc.dec",
234 "OMX.SEC.avcdec",
235 "OMX.SEC.MPEG4.Decoder",
236 "OMX.SEC.mpeg4.dec",
237 "OMX.SEC.vc1.dec",
238 NULL
240 for (const char **ptr = nopadding_decoders; *ptr; ptr++) {
241 if (!strcmp(*ptr, name))
242 return 1;
244 return 0;
247 /*****************************************************************************
248 * Logging utility functions
249 *****************************************************************************/
250 const char *StateToString(OMX_STATETYPE state)
252 static const char *psz_names[] = {
253 "OMX_StateInvalid", "OMX_StateLoaded", "OMX_StateIdle",
254 "OMX_StateExecuting", "OMX_StatePause", "OMX_StateWaitForResources",
255 "OMX_State unknown"
258 if((unsigned int)state > sizeof(psz_names)/sizeof(char*)-1)
259 state = (OMX_STATETYPE)(sizeof(psz_names)/sizeof(char*)-1);
260 return psz_names[state];
263 const char *CommandToString(OMX_COMMANDTYPE command)
265 static const char *psz_names[] = {
266 "OMX_CommandStateSet", "OMX_CommandFlush", "OMX_CommandPortDisable",
267 "OMX_CommandPortEnable", "OMX_CommandMarkBuffer",
268 "OMX_Command unknown"
271 if((unsigned int)command > sizeof(psz_names)/sizeof(char*)-1)
272 command = (OMX_COMMANDTYPE)(sizeof(psz_names)/sizeof(char*)-1);
273 return psz_names[command];
276 const char *EventToString(OMX_EVENTTYPE event)
278 static const char *psz_names[] = {
279 "OMX_EventCmdComplete", "OMX_EventError", "OMX_EventMark",
280 "OMX_EventPortSettingsChanged", "OMX_EventBufferFlag",
281 "OMX_EventResourcesAcquired", "OMX_EventComponentResumed",
282 "OMX_EventDynamicResourcesAvailable", "OMX_EventPortFormatDetected",
283 "OMX_Event unknown"
286 if((unsigned int)event > sizeof(psz_names)/sizeof(char*)-1)
287 event = (OMX_EVENTTYPE)(sizeof(psz_names)/sizeof(char*)-1);
288 return psz_names[event];
291 const char *ErrorToString(OMX_ERRORTYPE error)
293 static const char *psz_names[] = {
294 "OMX_ErrorInsufficientResources", "OMX_ErrorUndefined",
295 "OMX_ErrorInvalidComponentName", "OMX_ErrorComponentNotFound",
296 "OMX_ErrorInvalidComponent", "OMX_ErrorBadParameter",
297 "OMX_ErrorNotImplemented", "OMX_ErrorUnderflow",
298 "OMX_ErrorOverflow", "OMX_ErrorHardware", "OMX_ErrorInvalidState",
299 "OMX_ErrorStreamCorrupt", "OMX_ErrorPortsNotCompatible",
300 "OMX_ErrorResourcesLost", "OMX_ErrorNoMore", "OMX_ErrorVersionMismatch",
301 "OMX_ErrorNotReady", "OMX_ErrorTimeout", "OMX_ErrorSameState",
302 "OMX_ErrorResourcesPreempted", "OMX_ErrorPortUnresponsiveDuringAllocation",
303 "OMX_ErrorPortUnresponsiveDuringDeallocation",
304 "OMX_ErrorPortUnresponsiveDuringStop", "OMX_ErrorIncorrectStateTransition",
305 "OMX_ErrorIncorrectStateOperation", "OMX_ErrorUnsupportedSetting",
306 "OMX_ErrorUnsupportedIndex", "OMX_ErrorBadPortIndex",
307 "OMX_ErrorPortUnpopulated", "OMX_ErrorComponentSuspended",
308 "OMX_ErrorDynamicResourcesUnavailable", "OMX_ErrorMbErrorsInFrame",
309 "OMX_ErrorFormatNotDetected", "OMX_ErrorContentPipeOpenFailed",
310 "OMX_ErrorContentPipeCreationFailed", "OMX_ErrorSeperateTablesUsed",
311 "OMX_ErrorTunnelingUnsupported",
312 "OMX_Error unknown"
315 if(error == OMX_ErrorNone) return "OMX_ErrorNone";
317 error -= OMX_ErrorInsufficientResources;
319 if((unsigned int)error > sizeof(psz_names)/sizeof(char*)-1)
320 error = (OMX_STATETYPE)(sizeof(psz_names)/sizeof(char*)-1);
321 return psz_names[error];
324 /*****************************************************************************
325 * fourcc -> omx id mapping
326 *****************************************************************************/
327 static const struct
329 vlc_fourcc_t i_fourcc;
330 OMX_VIDEO_CODINGTYPE i_codec;
331 const char *psz_role;
333 } video_format_table[] =
335 { VLC_CODEC_MPGV, OMX_VIDEO_CodingMPEG2, "video_decoder.mpeg2" },
336 { VLC_CODEC_MP4V, OMX_VIDEO_CodingMPEG4, "video_decoder.mpeg4" },
337 { VLC_CODEC_H264, OMX_VIDEO_CodingAVC, "video_decoder.avc" },
338 { VLC_CODEC_H263, OMX_VIDEO_CodingH263, "video_decoder.h263" },
339 { VLC_CODEC_WMV1, OMX_VIDEO_CodingWMV, "video_decoder.wmv1" },
340 { VLC_CODEC_WMV2, OMX_VIDEO_CodingWMV, "video_decoder.wmv2" },
341 { VLC_CODEC_WMV3, OMX_VIDEO_CodingWMV, "video_decoder.wmv" },
342 { VLC_CODEC_VC1, OMX_VIDEO_CodingWMV, "video_decoder.wmv" },
343 { VLC_CODEC_MJPG, OMX_VIDEO_CodingMJPEG, "video_decoder.jpeg" },
344 { VLC_CODEC_MJPG, OMX_VIDEO_CodingMJPEG, "video_decoder.mjpeg" },
345 { VLC_CODEC_RV10, OMX_VIDEO_CodingRV, "video_decoder.rv" },
346 { VLC_CODEC_RV20, OMX_VIDEO_CodingRV, "video_decoder.rv" },
347 { VLC_CODEC_RV30, OMX_VIDEO_CodingRV, "video_decoder.rv" },
348 { VLC_CODEC_RV40, OMX_VIDEO_CodingRV, "video_decoder.rv" },
349 { 0, 0, 0 }
352 static const struct
354 vlc_fourcc_t i_fourcc;
355 OMX_AUDIO_CODINGTYPE i_codec;
356 const char *psz_role;
358 } audio_format_table[] =
360 { VLC_CODEC_AMR_NB, OMX_AUDIO_CodingAMR, "audio_decoder.amrnb" },
361 { VLC_CODEC_AMR_WB, OMX_AUDIO_CodingAMR, "audio_decoder.amrwb" },
362 { VLC_CODEC_MP4A, OMX_AUDIO_CodingAAC, "audio_decoder.aac" },
363 { VLC_CODEC_S16N, OMX_AUDIO_CodingPCM, "audio_decoder.pcm" },
364 { VLC_CODEC_MP3, OMX_AUDIO_CodingMP3, "audio_decoder.mp3" },
365 { 0, 0, 0 }
368 static const struct
370 vlc_fourcc_t i_fourcc;
371 OMX_VIDEO_CODINGTYPE i_codec;
372 const char *psz_role;
374 } video_enc_format_table[] =
376 { VLC_CODEC_MPGV, OMX_VIDEO_CodingMPEG2, "video_encoder.mpeg2" },
377 { VLC_CODEC_MP4V, OMX_VIDEO_CodingMPEG4, "video_encoder.mpeg4" },
378 { VLC_CODEC_H264, OMX_VIDEO_CodingAVC, "video_encoder.avc" },
379 { VLC_CODEC_H263, OMX_VIDEO_CodingH263, "video_encoder.h263" },
380 { VLC_CODEC_WMV1, OMX_VIDEO_CodingWMV, "video_encoder.wmv" },
381 { VLC_CODEC_WMV2, OMX_VIDEO_CodingWMV, "video_encoder.wmv" },
382 { VLC_CODEC_WMV3, OMX_VIDEO_CodingWMV, "video_encoder.wmv" },
383 { VLC_CODEC_MJPG, OMX_VIDEO_CodingMJPEG, "video_encoder.jpeg" },
384 { VLC_CODEC_RV10, OMX_VIDEO_CodingRV, "video_encoder.rv" },
385 { VLC_CODEC_RV20, OMX_VIDEO_CodingRV, "video_encoder.rv" },
386 { VLC_CODEC_RV30, OMX_VIDEO_CodingRV, "video_encoder.rv" },
387 { VLC_CODEC_RV40, OMX_VIDEO_CodingRV, "video_encoder.rv" },
388 { 0, 0, 0 }
391 static const struct
393 vlc_fourcc_t i_fourcc;
394 OMX_AUDIO_CODINGTYPE i_codec;
395 const char *psz_role;
397 } audio_enc_format_table[] =
399 { VLC_CODEC_AMR_NB, OMX_AUDIO_CodingAMR, "audio_encoder.amrnb" },
400 { VLC_CODEC_AMR_WB, OMX_AUDIO_CodingAMR, "audio_encoder.amrwb" },
401 { VLC_CODEC_MP4A, OMX_AUDIO_CodingAAC, "audio_encoder.aac" },
402 { VLC_CODEC_S16N, OMX_AUDIO_CodingPCM, "audio_encoder.pcm" },
403 { 0, 0, 0 }
406 static const struct
408 vlc_fourcc_t i_fourcc;
409 OMX_COLOR_FORMATTYPE i_codec;
410 unsigned int i_size_mul;
411 unsigned int i_line_mul;
412 unsigned int i_line_chroma_div;
414 } chroma_format_table[] =
416 { VLC_CODEC_I420, OMX_COLOR_FormatYUV420Planar, 3, 1, 2 },
417 { VLC_CODEC_I420, OMX_COLOR_FormatYUV420PackedPlanar, 3, 1, 2 },
418 { VLC_CODEC_NV12, OMX_COLOR_FormatYUV420SemiPlanar, 3, 1, 1 },
419 { VLC_CODEC_NV21, OMX_QCOM_COLOR_FormatYVU420SemiPlanar, 3, 1, 1 },
420 { VLC_CODEC_NV12, OMX_TI_COLOR_FormatYUV420PackedSemiPlanar, 3, 1, 2 },
421 { VLC_CODEC_NV12, QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka, 3, 1, 1 },
422 { VLC_CODEC_YUYV, OMX_COLOR_FormatYCbYCr, 4, 2, 0 },
423 { VLC_CODEC_YVYU, OMX_COLOR_FormatYCrYCb, 4, 2, 0 },
424 { VLC_CODEC_UYVY, OMX_COLOR_FormatCbYCrY, 4, 2, 0 },
425 { VLC_CODEC_VYUY, OMX_COLOR_FormatCrYCbY, 4, 2, 0 },
426 { 0, 0, 0, 0, 0 }
429 int GetOmxVideoFormat( vlc_fourcc_t i_fourcc,
430 OMX_VIDEO_CODINGTYPE *pi_omx_codec,
431 const char **ppsz_name )
433 unsigned int i;
435 i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc );
437 for( i = 0; video_format_table[i].i_codec != 0; i++ )
438 if( video_format_table[i].i_fourcc == i_fourcc ) break;
440 if( pi_omx_codec ) *pi_omx_codec = video_format_table[i].i_codec;
441 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( VIDEO_ES, i_fourcc );
442 return !!video_format_table[i].i_codec;
445 int GetVlcVideoFormat( OMX_VIDEO_CODINGTYPE i_omx_codec,
446 vlc_fourcc_t *pi_fourcc, const char **ppsz_name )
448 unsigned int i;
450 for( i = 0; video_format_table[i].i_codec != 0; i++ )
451 if( video_format_table[i].i_codec == i_omx_codec ) break;
453 if( pi_fourcc ) *pi_fourcc = video_format_table[i].i_fourcc;
454 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( VIDEO_ES,
455 video_format_table[i].i_fourcc );
456 return !!video_format_table[i].i_fourcc;
459 static const char *GetOmxVideoRole( vlc_fourcc_t i_fourcc )
461 unsigned int i;
463 i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc );
465 for( i = 0; video_format_table[i].i_codec != 0; i++ )
466 if( video_format_table[i].i_fourcc == i_fourcc ) break;
468 return video_format_table[i].psz_role;
471 static const char *GetOmxVideoEncRole( vlc_fourcc_t i_fourcc )
473 unsigned int i;
475 i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc );
477 for( i = 0; video_enc_format_table[i].i_codec != 0; i++ )
478 if( video_enc_format_table[i].i_fourcc == i_fourcc ) break;
480 return video_enc_format_table[i].psz_role;
483 int GetOmxAudioFormat( vlc_fourcc_t i_fourcc,
484 OMX_AUDIO_CODINGTYPE *pi_omx_codec,
485 const char **ppsz_name )
487 unsigned int i;
489 i_fourcc = vlc_fourcc_GetCodec( AUDIO_ES, i_fourcc );
491 for( i = 0; audio_format_table[i].i_codec != 0; i++ )
492 if( audio_format_table[i].i_fourcc == i_fourcc ) break;
494 if( pi_omx_codec ) *pi_omx_codec = audio_format_table[i].i_codec;
495 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( AUDIO_ES, i_fourcc );
496 return !!audio_format_table[i].i_codec;
499 int OmxToVlcAudioFormat( OMX_AUDIO_CODINGTYPE i_omx_codec,
500 vlc_fourcc_t *pi_fourcc, const char **ppsz_name )
502 unsigned int i;
504 for( i = 0; audio_format_table[i].i_codec != 0; i++ )
505 if( audio_format_table[i].i_codec == i_omx_codec ) break;
507 if( pi_fourcc ) *pi_fourcc = audio_format_table[i].i_fourcc;
508 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( AUDIO_ES,
509 audio_format_table[i].i_fourcc );
510 return !!audio_format_table[i].i_fourcc;
513 static const char *GetOmxAudioRole( vlc_fourcc_t i_fourcc )
515 unsigned int i;
517 i_fourcc = vlc_fourcc_GetCodec( AUDIO_ES, i_fourcc );
519 for( i = 0; audio_format_table[i].i_codec != 0; i++ )
520 if( audio_format_table[i].i_fourcc == i_fourcc ) break;
522 return audio_format_table[i].psz_role;
525 static const char *GetOmxAudioEncRole( vlc_fourcc_t i_fourcc )
527 unsigned int i;
529 i_fourcc = vlc_fourcc_GetCodec( AUDIO_ES, i_fourcc );
531 for( i = 0; audio_enc_format_table[i].i_codec != 0; i++ )
532 if( audio_enc_format_table[i].i_fourcc == i_fourcc ) break;
534 return audio_enc_format_table[i].psz_role;
537 const char *GetOmxRole( vlc_fourcc_t i_fourcc, int i_cat, bool b_enc )
539 if(b_enc)
540 return i_cat == VIDEO_ES ?
541 GetOmxVideoEncRole( i_fourcc ) : GetOmxAudioEncRole( i_fourcc );
542 else
543 return i_cat == VIDEO_ES ?
544 GetOmxVideoRole( i_fourcc ) : GetOmxAudioRole( i_fourcc );
547 int GetOmxChromaFormat( vlc_fourcc_t i_fourcc,
548 OMX_COLOR_FORMATTYPE *pi_omx_codec,
549 const char **ppsz_name )
551 unsigned int i;
553 i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc );
555 for( i = 0; chroma_format_table[i].i_codec != 0; i++ )
556 if( chroma_format_table[i].i_fourcc == i_fourcc ) break;
558 if( pi_omx_codec ) *pi_omx_codec = chroma_format_table[i].i_codec;
559 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( VIDEO_ES, i_fourcc );
560 return !!chroma_format_table[i].i_codec;
563 int GetVlcChromaFormat( OMX_COLOR_FORMATTYPE i_omx_codec,
564 vlc_fourcc_t *pi_fourcc, const char **ppsz_name )
566 unsigned int i;
568 for( i = 0; chroma_format_table[i].i_codec != 0; i++ )
569 if( chroma_format_table[i].i_codec == i_omx_codec ) break;
571 if( pi_fourcc ) *pi_fourcc = chroma_format_table[i].i_fourcc;
572 if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( VIDEO_ES,
573 chroma_format_table[i].i_fourcc );
574 return !!chroma_format_table[i].i_fourcc;
577 int GetVlcChromaSizes( vlc_fourcc_t i_fourcc,
578 unsigned int width, unsigned int height,
579 unsigned int *size, unsigned int *pitch,
580 unsigned int *chroma_pitch_div )
582 unsigned int i;
584 i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc );
586 for( i = 0; chroma_format_table[i].i_codec != 0; i++ )
587 if( chroma_format_table[i].i_fourcc == i_fourcc ) break;
589 /* Align on macroblock boundary */
590 width = (width + 15) & ~0xF;
591 height = (height + 15) & ~0xF;
593 if( size ) *size = width * height * chroma_format_table[i].i_size_mul / 2;
594 if( pitch ) *pitch = width * chroma_format_table[i].i_line_mul;
595 if( chroma_pitch_div )
596 *chroma_pitch_div = chroma_format_table[i].i_line_chroma_div;
597 return !!chroma_format_table[i].i_codec;
600 /*****************************************************************************
601 * Functions to deal with audio format parameters
602 *****************************************************************************/
603 static const struct {
604 OMX_AUDIO_CODINGTYPE encoding;
605 OMX_INDEXTYPE index;
606 int size;
607 } audio_encoding_param[] =
608 { { OMX_AUDIO_CodingPCM, OMX_IndexParamAudioPcm,
609 sizeof(OMX_AUDIO_PARAM_PCMMODETYPE) },
610 { OMX_AUDIO_CodingADPCM, OMX_IndexParamAudioAdpcm,
611 sizeof(OMX_AUDIO_PARAM_ADPCMTYPE) },
612 { OMX_AUDIO_CodingAMR, OMX_IndexParamAudioAmr,
613 sizeof(OMX_AUDIO_PARAM_AMRTYPE) },
614 { OMX_AUDIO_CodingG711, OMX_IndexParamAudioPcm,
615 sizeof(OMX_AUDIO_PARAM_PCMMODETYPE) },
616 { OMX_AUDIO_CodingG723, OMX_IndexParamAudioG723,
617 sizeof(OMX_AUDIO_PARAM_G723TYPE) },
618 { OMX_AUDIO_CodingG726, OMX_IndexParamAudioG726,
619 sizeof(OMX_AUDIO_PARAM_G726TYPE) },
620 { OMX_AUDIO_CodingG729, OMX_IndexParamAudioG729,
621 sizeof(OMX_AUDIO_PARAM_G729TYPE) },
622 { OMX_AUDIO_CodingAAC, OMX_IndexParamAudioAac,
623 sizeof(OMX_AUDIO_PARAM_AACPROFILETYPE) },
624 { OMX_AUDIO_CodingMP3, OMX_IndexParamAudioMp3,
625 sizeof(OMX_AUDIO_PARAM_MP3TYPE) },
626 { OMX_AUDIO_CodingSBC, OMX_IndexParamAudioSbc,
627 sizeof(OMX_AUDIO_PARAM_SBCTYPE) },
628 { OMX_AUDIO_CodingVORBIS, OMX_IndexParamAudioVorbis,
629 sizeof(OMX_AUDIO_PARAM_VORBISTYPE) },
630 { OMX_AUDIO_CodingWMA, OMX_IndexParamAudioWma,
631 sizeof(OMX_AUDIO_PARAM_WMATYPE) },
632 { OMX_AUDIO_CodingRA, OMX_IndexParamAudioRa,
633 sizeof(OMX_AUDIO_PARAM_RATYPE) },
634 { OMX_AUDIO_CodingUnused, 0, 0 }
637 static OMX_INDEXTYPE GetAudioParamFormatIndex(OMX_AUDIO_CODINGTYPE encoding)
639 int i;
641 for(i = 0; audio_encoding_param[i].encoding != OMX_AUDIO_CodingUnused &&
642 audio_encoding_param[i].encoding != encoding; i++);
644 return audio_encoding_param[i].index;
647 unsigned int GetAudioParamSize(OMX_INDEXTYPE index)
649 int i;
651 for(i = 0; audio_encoding_param[i].encoding != OMX_AUDIO_CodingUnused &&
652 audio_encoding_param[i].index != index; i++);
654 return audio_encoding_param[i].size;
657 OMX_ERRORTYPE SetAudioParameters(OMX_HANDLETYPE handle,
658 OmxFormatParam *param, OMX_U32 i_port, OMX_AUDIO_CODINGTYPE encoding,
659 vlc_fourcc_t i_codec, uint8_t i_channels, unsigned int i_samplerate,
660 unsigned int i_bitrate, unsigned int i_bps, unsigned int i_blocksize)
662 OMX_INDEXTYPE index;
664 switch(encoding)
666 case OMX_AUDIO_CodingPCM:
667 case OMX_AUDIO_CodingG711:
668 OMX_INIT_STRUCTURE(param->pcm);
669 param->pcm.nChannels = i_channels;
670 param->pcm.nSamplingRate = i_samplerate;
671 param->pcm.eNumData = OMX_NumericalDataSigned;
672 param->pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
673 param->pcm.eEndian = OMX_EndianLittle;
674 param->pcm.bInterleaved = OMX_TRUE;
675 param->pcm.nBitPerSample = i_bps;
676 param->pcm.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
677 if(i_channels == 2)
679 param->pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
680 param->pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
682 break;
683 case OMX_AUDIO_CodingADPCM:
684 OMX_INIT_STRUCTURE(param->adpcm);
685 param->adpcm.nChannels = i_channels;
686 param->adpcm.nSampleRate = i_samplerate;
687 param->adpcm.nBitsPerSample = i_bps;
688 break;
689 case OMX_AUDIO_CodingAMR:
690 OMX_INIT_STRUCTURE(param->amr);
691 param->amr.nChannels = i_channels;
692 param->amr.nBitRate = i_bitrate;
693 if (i_codec == VLC_CODEC_AMR_WB)
694 param->amr.eAMRBandMode = OMX_AUDIO_AMRBandModeWB0;
695 else
696 param->amr.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0;
697 param->amr.eAMRDTXMode = OMX_AUDIO_AMRDTXModeOff;
698 param->amr.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
699 break;
700 case OMX_AUDIO_CodingG723:
701 OMX_INIT_STRUCTURE(param->g723);
702 param->g723.nChannels = i_channels;
703 param->g723.bDTX = OMX_FALSE;
704 param->g723.eBitRate = OMX_AUDIO_G723ModeUnused;
705 param->g723.bHiPassFilter = OMX_TRUE;
706 param->g723.bPostFilter = OMX_TRUE;
707 break;
708 case OMX_AUDIO_CodingG726:
709 OMX_INIT_STRUCTURE(param->g726);
710 param->g726.nChannels = i_channels;
711 param->g726.eG726Mode = OMX_AUDIO_G726ModeUnused;
712 break;
713 case OMX_AUDIO_CodingG729:
714 OMX_INIT_STRUCTURE(param->g729);
715 param->g729.nChannels = i_channels;
716 param->g729.bDTX = OMX_FALSE;
717 param->g729.eBitType = OMX_AUDIO_G729;
718 break;
719 case OMX_AUDIO_CodingAAC:
720 OMX_INIT_STRUCTURE(param->aac);
721 param->aac.nChannels = i_channels;
722 param->aac.nSampleRate = i_samplerate;
723 param->aac.nBitRate = i_bitrate;
724 param->aac.nAudioBandWidth = 0;
725 param->aac.nFrameLength = 1024;
726 param->aac.nAACtools = OMX_AUDIO_AACToolAll;
727 param->aac.nAACERtools = OMX_AUDIO_AACERAll;
728 param->aac.eAACProfile = OMX_AUDIO_AACObjectLC;
729 param->aac.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
730 param->aac.eChannelMode = i_channels > 1 ?
731 OMX_AUDIO_ChannelModeStereo : OMX_AUDIO_ChannelModeMono;
732 break;
733 case OMX_AUDIO_CodingMP3:
734 OMX_INIT_STRUCTURE(param->mp3);
735 param->mp3.nChannels = i_channels;
736 param->mp3.nSampleRate = i_samplerate;
737 param->mp3.nBitRate = i_bitrate;
738 param->mp3.eChannelMode = i_channels > 1 ?
739 OMX_AUDIO_ChannelModeStereo : OMX_AUDIO_ChannelModeMono;
740 param->mp3.eFormat = OMX_AUDIO_MP3StreamFormatMP1Layer3;
741 break;
742 case OMX_AUDIO_CodingWMA:
743 OMX_INIT_STRUCTURE(param->wma);
744 param->wma.nChannels = i_channels;
745 param->wma.nBitRate = i_bitrate;
746 param->wma.eFormat = OMX_AUDIO_WMAFormatUnused;
747 param->wma.eProfile = OMX_AUDIO_WMAProfileUnused;
748 param->wma.nSamplingRate = i_samplerate;
749 param->wma.nBlockAlign = i_blocksize;
750 param->wma.nEncodeOptions = 0;
751 param->wma.nSuperBlockAlign = 0;
752 break;
753 case OMX_AUDIO_CodingRA:
754 OMX_INIT_STRUCTURE(param->ra);
755 param->ra.nChannels = i_channels;
756 param->ra.nSamplingRate = i_samplerate;
757 param->ra.nBitsPerFrame = i_bps;
758 param->ra.nSamplePerFrame = 0;
759 param->ra.nCouplingQuantBits = 0;
760 param->ra.nCouplingStartRegion = 0;
761 param->ra.nNumRegions = 0;
762 param->ra.eFormat = OMX_AUDIO_RAFormatUnused;
763 break;
764 case OMX_AUDIO_CodingVORBIS:
765 OMX_INIT_STRUCTURE(param->vorbis);
766 param->vorbis.nChannels = i_channels;
767 param->vorbis.nBitRate = i_bitrate;
768 param->vorbis.nMinBitRate = 0;
769 param->vorbis.nMaxBitRate = i_bitrate;
770 param->vorbis.nSampleRate = i_samplerate;
771 param->vorbis.nAudioBandWidth = 0;
772 param->vorbis.nQuality = 3;
773 param->vorbis.bManaged = OMX_FALSE;
774 param->vorbis.bDownmix = OMX_FALSE;
775 break;
776 default:
777 return OMX_ErrorBadParameter;
780 param->common.nPortIndex = i_port;
782 index = GetAudioParamFormatIndex(encoding);
783 return OMX_SetParameter(handle, index, param);
786 OMX_ERRORTYPE GetAudioParameters(OMX_HANDLETYPE handle,
787 OmxFormatParam *param, OMX_U32 i_port, OMX_AUDIO_CODINGTYPE encoding,
788 uint8_t *pi_channels, unsigned int *pi_samplerate,
789 unsigned int *pi_bitrate, unsigned int *pi_bps, unsigned int *pi_blocksize)
791 int i_channels = 0, i_samplerate = 0, i_bitrate = 0;
792 int i_bps = 0, i_blocksize = 0;
793 OMX_ERRORTYPE omx_error;
794 OMX_INDEXTYPE index;
796 OMX_INIT_COMMON(param->common);
797 param->common.nPortIndex = i_port;
798 index = GetAudioParamFormatIndex(encoding);
799 if(!index) return OMX_ErrorNotImplemented;
801 param->common.nSize = GetAudioParamSize(index);
802 omx_error = OMX_GetParameter(handle, index, param);
803 if(omx_error != OMX_ErrorNone) return omx_error;
805 switch(encoding)
807 case OMX_AUDIO_CodingPCM:
808 case OMX_AUDIO_CodingG711:
809 i_channels = param->pcm.nChannels;
810 i_samplerate = param->pcm.nSamplingRate;
811 i_bps = param->pcm.nBitPerSample;
812 break;
813 case OMX_AUDIO_CodingADPCM:
814 i_channels = param->adpcm.nChannels;
815 i_samplerate = param->adpcm.nSampleRate;
816 i_bps = param->adpcm.nBitsPerSample;
817 break;
818 case OMX_AUDIO_CodingAMR:
819 i_channels = param->amr.nChannels;
820 i_bitrate = param->amr.nBitRate;
821 i_samplerate = 8000;
822 break;
823 case OMX_AUDIO_CodingG723:
824 i_channels = param->g723.nChannels;
825 break;
826 case OMX_AUDIO_CodingG726:
827 i_channels = param->g726.nChannels;
828 break;
829 case OMX_AUDIO_CodingG729:
830 i_channels = param->g729.nChannels;
831 break;
832 case OMX_AUDIO_CodingAAC:
833 i_channels = param->aac.nChannels;
834 i_samplerate = param->aac.nSampleRate;
835 i_bitrate = param->aac.nBitRate;
836 i_channels = param->aac.eChannelMode == OMX_AUDIO_ChannelModeStereo ? 2 : 1;
837 break;
838 case OMX_AUDIO_CodingMP3:
839 i_channels = param->mp3.nChannels;
840 i_samplerate = param->mp3.nSampleRate;
841 i_bitrate = param->mp3.nBitRate;
842 i_channels = param->mp3.eChannelMode == OMX_AUDIO_ChannelModeStereo ? 2 : 1;
843 break;
844 case OMX_AUDIO_CodingVORBIS:
845 i_channels = param->vorbis.nChannels;
846 i_bitrate = param->vorbis.nBitRate;
847 i_samplerate = param->vorbis.nSampleRate;
848 break;
849 case OMX_AUDIO_CodingWMA:
850 i_channels = param->wma.nChannels;
851 i_bitrate = param->wma.nBitRate;
852 i_samplerate = param->wma.nSamplingRate;
853 i_blocksize = param->wma.nBlockAlign;
854 break;
855 case OMX_AUDIO_CodingRA:
856 i_channels = param->ra.nChannels;
857 i_samplerate = param->ra.nSamplingRate;
858 i_bps = param->ra.nBitsPerFrame;
859 break;
860 default:
861 return OMX_ErrorBadParameter;
864 if(pi_channels) *pi_channels = i_channels;
865 if(pi_samplerate) *pi_samplerate = i_samplerate;
866 if(pi_bitrate) *pi_bitrate = i_bitrate;
867 if(pi_bps) *pi_bps = i_bps;
868 if(pi_blocksize) *pi_blocksize = i_blocksize;
869 return OMX_ErrorNone;
872 /*****************************************************************************
873 * PrintOmx: print component summary
874 *****************************************************************************/
875 void PrintOmx(decoder_t *p_dec, OMX_HANDLETYPE omx_handle, OMX_U32 i_port)
877 OMX_PARAM_PORTDEFINITIONTYPE definition;
878 OMX_PORT_PARAM_TYPE param;
879 OMX_ERRORTYPE omx_error;
880 unsigned int i, j;
882 /* Find the input / output ports */
883 OMX_INIT_STRUCTURE(param);
884 OMX_INIT_STRUCTURE(definition);
886 for(i = 0; i < 3; i++)
888 omx_error = OMX_GetParameter(omx_handle, OMX_IndexParamAudioInit + i, &param);
889 if(omx_error != OMX_ErrorNone) continue;
891 if(i_port == OMX_ALL)
892 msg_Dbg( p_dec, "found %i %s ports", (int)param.nPorts,
893 i == 0 ? "audio" : i == 1 ? "image" : "video" );
895 for(j = 0; j < param.nPorts; j++)
897 unsigned int i_samplerate, i_bitrate;
898 unsigned int i_bitspersample, i_blockalign;
899 uint8_t i_channels;
900 OmxFormatParam format_param;
901 vlc_fourcc_t i_fourcc;
902 const char *psz_name;
903 OMX_CONFIG_RECTTYPE crop_rect;
905 if(i_port != OMX_ALL && i_port != param.nStartPortNumber + j)
906 continue;
908 /* Get port definition */
909 definition.nPortIndex = param.nStartPortNumber + j;
910 omx_error = OMX_GetParameter(omx_handle, OMX_IndexParamPortDefinition,
911 &definition);
912 if(omx_error != OMX_ErrorNone) continue;
914 OMX_PARAM_U32TYPE u32param;
915 OMX_INIT_STRUCTURE(u32param);
916 u32param.nPortIndex = param.nStartPortNumber + j;
917 omx_error = OMX_GetParameter(omx_handle, OMX_IndexParamNumAvailableStreams,
918 (OMX_PTR)&u32param);
920 msg_Dbg( p_dec, "-> %s %i (%i streams) (%i:%i:%i buffers) (%i,%i) %s",
921 definition.eDir == OMX_DirOutput ? "output" : "input",
922 (int)definition.nPortIndex, (int)u32param.nU32,
923 (int)definition.nBufferCountActual,
924 (int)definition.nBufferCountMin, (int)definition.nBufferSize,
925 (int)definition.bBuffersContiguous,
926 (int)definition.nBufferAlignment,
927 definition.bEnabled ? "enabled" : "disabled" );
929 switch(definition.eDomain)
931 case OMX_PortDomainVideo:
933 if(definition.format.video.eCompressionFormat)
934 GetVlcVideoFormat( definition.format.video.eCompressionFormat,
935 &i_fourcc, &psz_name );
936 else
937 GetVlcChromaFormat( definition.format.video.eColorFormat,
938 &i_fourcc, &psz_name );
940 OMX_INIT_STRUCTURE(crop_rect);
941 crop_rect.nPortIndex = definition.nPortIndex;
942 omx_error = OMX_GetConfig(omx_handle, OMX_IndexConfigCommonOutputCrop, &crop_rect);
943 if (omx_error != OMX_ErrorNone)
945 crop_rect.nLeft = crop_rect.nTop = 0;
946 crop_rect.nWidth = definition.format.video.nFrameWidth;
947 crop_rect.nHeight = definition.format.video.nFrameHeight;
950 msg_Dbg( p_dec, " -> video %s %ix%i@%.2f (%i,%i) (%i,%i) (%i,%i,%i,%i)", psz_name,
951 (int)definition.format.video.nFrameWidth,
952 (int)definition.format.video.nFrameHeight,
953 (float)definition.format.video.xFramerate/(float)(1<<16),
954 (int)definition.format.video.eCompressionFormat,
955 (int)definition.format.video.eColorFormat,
956 (int)definition.format.video.nStride,
957 (int)definition.format.video.nSliceHeight,
958 (int)crop_rect.nLeft, (int)crop_rect.nTop,
959 (int)crop_rect.nWidth, (int)crop_rect.nHeight);
960 break;
962 case OMX_PortDomainAudio:
964 OmxToVlcAudioFormat( definition.format.audio.eEncoding,
965 &i_fourcc, &psz_name );
967 GetAudioParameters(omx_handle, &format_param,
968 definition.nPortIndex,
969 definition.format.audio.eEncoding,
970 &i_channels, &i_samplerate, &i_bitrate,
971 &i_bitspersample, &i_blockalign);
973 msg_Dbg( p_dec, " -> audio %s (%i) %i,%i,%i,%i,%i", psz_name,
974 (int)definition.format.audio.eEncoding,
975 i_channels, i_samplerate, i_bitrate, i_bitspersample,
976 i_blockalign);
977 break;
979 default: break;