]> git.sesse.net Git - vlc/blob - modules/codec/omxil/omxil.c
android/jni: use a libvlcjni function to attach/detach java thread
[vlc] / modules / codec / omxil / omxil.c
1 /*****************************************************************************
2  * omxil.c: Video decoder module making use of OpenMAX IL components.
3  *****************************************************************************
4  * Copyright (C) 2010 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Gildas Bazin <gbazin@videolan.org>
8  *
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.
13  *
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.
18  *
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  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <limits.h>
32
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_codec.h>
36 #include <vlc_block_helper.h>
37 #include <vlc_cpu.h>
38 #include "../h264_nal.h"
39 #include "../hevc_nal.h"
40
41 #include "omxil.h"
42 #include "omxil_core.h"
43 #include "OMX_Broadcom.h"
44
45 #if defined(USE_IOMX)
46 #include <dlfcn.h>
47 #include <jni.h>
48 #include "android_opaque.h"
49 #endif
50
51 #ifndef NDEBUG
52 # define OMX_DBG(...) msg_Dbg( p_dec, __VA_ARGS__ )
53 #else
54 # define OMX_DBG(...)
55 #endif
56
57 #define SENTINEL_FLAG 0x10000
58
59 /* Defined in the broadcom version of OMX_Index.h */
60 #define OMX_IndexConfigRequestCallback 0x7f000063
61 #define OMX_IndexParamBrcmPixelAspectRatio 0x7f00004d
62 #define OMX_IndexParamBrcmVideoDecodeErrorConcealment 0x7f000080
63
64 /* Defined in the broadcom version of OMX_Core.h */
65 #define OMX_EventParamOrConfigChanged 0x7F000001
66
67 #if defined(USE_IOMX)
68 /* JNI functions to get/set an Android Surface object. */
69 #define THREAD_NAME "omxil"
70 extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
71 extern void jni_detach_thread();
72 extern jobject jni_LockAndGetAndroidJavaSurface();
73 extern void jni_UnlockAndroidSurface();
74 extern void jni_SetAndroidSurfaceSize(int width, int height, int visible_width, int visible_height, int sar_num, int sar_den);
75 extern bool jni_IsVideoPlayerActivityCreated();
76 #endif
77
78 /*****************************************************************************
79  * Local prototypes
80  *****************************************************************************/
81 static int  OpenDecoder( vlc_object_t * );
82 static int  OpenEncoder( vlc_object_t * );
83 static int  OpenGeneric( vlc_object_t *, bool b_encode );
84 static void CloseGeneric( vlc_object_t * );
85
86 static picture_t *DecodeVideo( decoder_t *, block_t ** );
87 static block_t *DecodeAudio ( decoder_t *, block_t ** );
88 static block_t *EncodeVideo( encoder_t *, picture_t * );
89
90 static OMX_ERRORTYPE OmxEventHandler( OMX_HANDLETYPE, OMX_PTR, OMX_EVENTTYPE,
91                                       OMX_U32, OMX_U32, OMX_PTR );
92 static OMX_ERRORTYPE OmxEmptyBufferDone( OMX_HANDLETYPE, OMX_PTR,
93                                          OMX_BUFFERHEADERTYPE * );
94 static OMX_ERRORTYPE OmxFillBufferDone( OMX_HANDLETYPE, OMX_PTR,
95                                         OMX_BUFFERHEADERTYPE * );
96
97 #if defined(USE_IOMX)
98 static void *DequeueThread( void *data );
99 static void DisplayCallback( picture_sys_t* p_picsys );
100 static void UnlockCallback( picture_sys_t* p_picsys );
101 static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port );
102 static void HwBuffer_Destroy( decoder_t *p_dec, OmxPort *p_port );
103 static int  HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port );
104 static int  HwBuffer_FreeBuffers( decoder_t *p_dec, OmxPort *p_port );
105 static int  HwBuffer_Start( decoder_t *p_dec, OmxPort *p_port );
106 static int  HwBuffer_Stop( decoder_t *p_dec, OmxPort *p_port );
107 static int  HwBuffer_Join( decoder_t *p_dec, OmxPort *p_port );
108 static int  HwBuffer_GetPic( decoder_t *p_dec, OmxPort *p_port,
109                              picture_t **pp_pic );
110 static void HwBuffer_SetCrop( decoder_t *p_dec, OmxPort *p_port,
111                               OMX_CONFIG_RECTTYPE *p_rect );
112 static void HwBuffer_ChangeState( decoder_t *p_dec, OmxPort *p_port,
113                                   int i_index, int i_state );
114
115 #define HWBUFFER_LOCK() vlc_mutex_lock( get_android_opaque_mutex() )
116 #define HWBUFFER_UNLOCK() vlc_mutex_unlock( get_android_opaque_mutex() )
117 #define HWBUFFER_WAIT(p_port) vlc_cond_wait( &(p_port)->p_hwbuf->wait, \
118                                               get_android_opaque_mutex() )
119 #define HWBUFFER_BROADCAST(p_port) vlc_cond_broadcast( &(p_port)->p_hwbuf->wait )
120
121 #else
122 static inline int HwBuffer_dummy( )
123 {
124     return 0;
125 }
126 #define HwBuffer_Init(p_dec, p_port) do { } while (0)
127 #define HwBuffer_Destroy(p_dec, p_port) do { } while (0)
128 #define HwBuffer_AllocateBuffers(p_dec, p_port) HwBuffer_dummy()
129 #define HwBuffer_FreeBuffers(p_dec, p_port) HwBuffer_dummy()
130 #define HwBuffer_Start(p_dec, p_port) HwBuffer_dummy()
131 #define HwBuffer_Stop(p_dec, p_port) HwBuffer_dummy()
132 #define HwBuffer_Join(p_dec, p_port) HwBuffer_dummy()
133 #define HwBuffer_GetPic(p_dec, p_port, pp_pic) HwBuffer_dummy()
134 #define HwBuffer_SetCrop(p_dec, p_port, p_rect) do { } while (0)
135
136 #define HWBUFFER_LOCK() do { } while (0)
137 #define HWBUFFER_UNLOCK() do { } while (0)
138 #define HWBUFFER_WAIT(p_port) do { } while (0)
139 #define HWBUFFER_BROADCAST(p_port) do { } while (0)
140 #endif
141
142 /*****************************************************************************
143  * Module descriptor
144  *****************************************************************************/
145 #define DIRECTRENDERING_TEXT N_("OMX direct rendering")
146 #define DIRECTRENDERING_LONGTEXT N_(\
147         "Enable OMX direct rendering.")
148
149 #define CFG_PREFIX "omxil-"
150 vlc_module_begin ()
151     set_description( N_("Audio/Video decoder (using OpenMAX IL)") )
152     set_category( CAT_INPUT )
153     set_subcategory( SUBCAT_INPUT_VCODEC )
154     set_section( N_("Decoding") , NULL )
155 #if defined(USE_IOMX)
156     /* For IOMX, don't enable it automatically via priorities,
157      * enable it only via the --codec iomx command line parameter when
158      * wanted. */
159     set_capability( "decoder", 0 )
160     add_bool(CFG_PREFIX "dr", true,
161              DIRECTRENDERING_TEXT, DIRECTRENDERING_LONGTEXT, true)
162 #else
163     set_capability( "decoder", 80 )
164 #endif
165     set_callbacks( OpenDecoder, CloseGeneric )
166
167     add_submodule ()
168     set_section( N_("Encoding") , NULL )
169     set_description( N_("Video encoder (using OpenMAX IL)") )
170     set_capability( "encoder", 0 )
171     set_callbacks( OpenEncoder, CloseGeneric )
172 vlc_module_end ()
173
174 /*****************************************************************************
175  * ImplementationSpecificWorkarounds: place-holder for implementation
176  * specific workarounds
177  *****************************************************************************/
178 static OMX_ERRORTYPE ImplementationSpecificWorkarounds(decoder_t *p_dec,
179     OmxPort *p_port, es_format_t *p_fmt)
180 {
181     decoder_sys_t *p_sys = p_dec->p_sys;
182     OMX_PARAM_PORTDEFINITIONTYPE *def = &p_port->definition;
183     size_t i_profile = 0xFFFF, i_level = 0xFFFF;
184
185     /* Try to find out the profile of the video */
186     if(p_fmt->i_cat == VIDEO_ES && def->eDir == OMX_DirInput &&
187             p_fmt->i_codec == VLC_CODEC_H264)
188         h264_get_profile_level(&p_dec->fmt_in, &i_profile, &i_level, &p_sys->i_nal_size_length);
189
190     if(!strcmp(p_sys->psz_component, "OMX.TI.Video.Decoder"))
191     {
192         if(p_fmt->i_cat == VIDEO_ES && def->eDir == OMX_DirInput &&
193            p_fmt->i_codec == VLC_CODEC_H264 &&
194            (i_profile != 66 || i_level > 30))
195         {
196             msg_Dbg(p_dec, "h264 profile/level not supported (0x%x, 0x%x)",
197                     i_profile, i_level);
198             return OMX_ErrorNotImplemented;
199         }
200
201         if(p_fmt->i_cat == VIDEO_ES && def->eDir == OMX_DirOutput &&
202            p_fmt->i_codec == VLC_CODEC_I420)
203         {
204             /* I420 xvideo is slow on OMAP */
205             def->format.video.eColorFormat = OMX_COLOR_FormatCbYCrY;
206             GetVlcChromaFormat( def->format.video.eColorFormat,
207                                 &p_fmt->i_codec, 0 );
208             GetVlcChromaSizes( p_fmt->i_codec,
209                                def->format.video.nFrameWidth,
210                                def->format.video.nFrameHeight,
211                                &p_port->i_frame_size, &p_port->i_frame_stride,
212                                &p_port->i_frame_stride_chroma_div );
213             def->format.video.nStride = p_port->i_frame_stride;
214             def->nBufferSize = p_port->i_frame_size;
215         }
216     }
217     else if(!strcmp(p_sys->psz_component, "OMX.st.video_encoder"))
218     {
219         if(p_fmt->i_cat == VIDEO_ES)
220         {
221             /* Bellagio's encoder doesn't encode the framerate in Q16 */
222             def->format.video.xFramerate >>= 16;
223         }
224     }
225 #if 0 /* FIXME: doesn't apply for HP Touchpad */
226     else if (!strncmp(p_sys->psz_component, "OMX.qcom.video.decoder.",
227                       strlen("OMX.qcom.video.decoder")))
228     {
229         /* qdsp6 refuses buffer size larger than 450K on input port */
230         if (def->nBufferSize > 450 * 1024)
231         {
232             def->nBufferSize = 450 * 1024;
233             p_port->i_frame_size = def->nBufferSize;
234         }
235     }
236 #endif
237 #ifdef RPI_OMX
238     else if (!strcmp(p_sys->psz_component, "OMX.broadcom.video_decode"))
239     {
240         /* Clear these fields before setting parameters, to allow the codec
241          * fill in what it wants (instead of rejecting whatever happened to
242          * be there. */
243         def->format.video.nStride = def->format.video.nSliceHeight = 0;
244     }
245 #endif
246
247     return OMX_ErrorNone;
248 }
249
250 /*****************************************************************************
251  * SetPortDefinition: set definition of the omx port based on the vlc format
252  *****************************************************************************/
253 static OMX_ERRORTYPE SetPortDefinition(decoder_t *p_dec, OmxPort *p_port,
254                                        es_format_t *p_fmt)
255 {
256     OMX_PARAM_PORTDEFINITIONTYPE *def = &p_port->definition;
257     OMX_ERRORTYPE omx_error;
258
259     omx_error = OMX_GetParameter(p_port->omx_handle,
260                                  OMX_IndexParamPortDefinition, def);
261     CHECK_ERROR(omx_error, "OMX_GetParameter failed (%x : %s)",
262                 omx_error, ErrorToString(omx_error));
263
264     switch(p_fmt->i_cat)
265     {
266     case VIDEO_ES:
267         def->format.video.nFrameWidth = p_fmt->video.i_width;
268         def->format.video.nFrameHeight = p_fmt->video.i_height;
269         if(def->format.video.eCompressionFormat == OMX_VIDEO_CodingUnused)
270             def->format.video.nStride = def->format.video.nFrameWidth;
271         if( p_fmt->video.i_frame_rate > 0 &&
272             p_fmt->video.i_frame_rate_base > 0 )
273             def->format.video.xFramerate = (p_fmt->video.i_frame_rate << 16) /
274                 p_fmt->video.i_frame_rate_base;
275
276         if(def->eDir == OMX_DirInput || p_dec->p_sys->b_enc)
277         {
278             if (def->eDir == OMX_DirInput && p_dec->p_sys->b_enc)
279                 def->nBufferSize = def->format.video.nFrameWidth *
280                   def->format.video.nFrameHeight * 2;
281             p_port->i_frame_size = def->nBufferSize;
282
283             if(!GetOmxVideoFormat(p_fmt->i_codec,
284                                   &def->format.video.eCompressionFormat, 0) )
285             {
286                 if(!GetOmxChromaFormat(p_fmt->i_codec,
287                                        &def->format.video.eColorFormat, 0) )
288                 {
289                     omx_error = OMX_ErrorNotImplemented;
290                     CHECK_ERROR(omx_error, "codec %4.4s doesn't match any OMX format",
291                                 (char *)&p_fmt->i_codec );
292                 }
293                 GetVlcChromaSizes( p_fmt->i_codec,
294                                    def->format.video.nFrameWidth,
295                                    def->format.video.nFrameHeight,
296                                    &p_port->i_frame_size, &p_port->i_frame_stride,
297                                    &p_port->i_frame_stride_chroma_div );
298                 def->format.video.nStride = p_port->i_frame_stride;
299                 def->nBufferSize = p_port->i_frame_size;
300             }
301         }
302         else
303         {
304             if( p_port->p_hwbuf )
305             {
306                 p_fmt->i_codec = VLC_CODEC_ANDROID_OPAQUE;
307                 break;
308             }
309
310             if( !GetVlcChromaFormat( def->format.video.eColorFormat,
311                                      &p_fmt->i_codec, 0 ) )
312             {
313                 omx_error = OMX_ErrorNotImplemented;
314                 CHECK_ERROR(omx_error, "OMX color format %i not supported",
315                             (int)def->format.video.eColorFormat );
316             }
317             GetVlcChromaSizes( p_fmt->i_codec,
318                                def->format.video.nFrameWidth,
319                                def->format.video.nFrameHeight,
320                                &p_port->i_frame_size, &p_port->i_frame_stride,
321                                &p_port->i_frame_stride_chroma_div );
322             def->format.video.nStride = p_port->i_frame_stride;
323             if (p_port->i_frame_size > def->nBufferSize)
324                 def->nBufferSize = p_port->i_frame_size;
325         }
326         break;
327
328     case AUDIO_ES:
329         p_port->i_frame_size = def->nBufferSize;
330         if(def->eDir == OMX_DirInput)
331         {
332             if(!GetOmxAudioFormat(p_fmt->i_codec,
333                                   &def->format.audio.eEncoding, 0) )
334             {
335                 omx_error = OMX_ErrorNotImplemented;
336                 CHECK_ERROR(omx_error, "codec %4.4s doesn't match any OMX format",
337                             (char *)&p_fmt->i_codec );
338             }
339         }
340         else
341         {
342             if( !OmxToVlcAudioFormat(def->format.audio.eEncoding,
343                                    &p_fmt->i_codec, 0 ) )
344             {
345                 omx_error = OMX_ErrorNotImplemented;
346                 CHECK_ERROR(omx_error, "OMX audio encoding %i not supported",
347                             (int)def->format.audio.eEncoding );
348             }
349         }
350         break;
351
352     default: return OMX_ErrorNotImplemented;
353     }
354
355     omx_error = ImplementationSpecificWorkarounds(p_dec, p_port, p_fmt);
356     CHECK_ERROR(omx_error, "ImplementationSpecificWorkarounds failed (%x : %s)",
357                 omx_error, ErrorToString(omx_error));
358
359     omx_error = OMX_SetParameter(p_port->omx_handle,
360                                  OMX_IndexParamPortDefinition, def);
361     CHECK_ERROR(omx_error, "OMX_SetParameter failed (%x : %s)",
362                 omx_error, ErrorToString(omx_error));
363
364     omx_error = OMX_GetParameter(p_port->omx_handle,
365                                  OMX_IndexParamPortDefinition, def);
366     CHECK_ERROR(omx_error, "OMX_GetParameter failed (%x : %s)",
367                 omx_error, ErrorToString(omx_error));
368
369     if(p_port->i_frame_size > def->nBufferSize)
370         def->nBufferSize = p_port->i_frame_size;
371     p_port->i_frame_size = def->nBufferSize;
372
373     /* Deal with audio params */
374     if(p_fmt->i_cat == AUDIO_ES)
375     {
376         omx_error = SetAudioParameters(p_port->omx_handle,
377                                        &p_port->format_param, def->nPortIndex,
378                                        def->format.audio.eEncoding,
379                                        p_fmt->i_codec,
380                                        p_fmt->audio.i_channels,
381                                        p_fmt->audio.i_rate,
382                                        p_fmt->i_bitrate,
383                                        p_fmt->audio.i_bitspersample,
384                                        p_fmt->audio.i_blockalign);
385         if (def->eDir == OMX_DirInput) {
386             CHECK_ERROR(omx_error, "SetAudioParameters failed (%x : %s)",
387                         omx_error, ErrorToString(omx_error));
388         } else if (omx_error != OMX_ErrorNone) {
389             msg_Warn(p_dec, "SetAudioParameters failed (%x : %s) on output port",
390                      omx_error, ErrorToString(omx_error));
391             omx_error = OMX_ErrorNone;
392         }
393     }
394     if (!strcmp(p_dec->p_sys->psz_component, "OMX.TI.DUCATI1.VIDEO.DECODER") &&
395                 def->eDir == OMX_DirOutput && !p_port->p_hwbuf)
396     {
397         /* When setting the output buffer size above, the decoder actually
398          * sets the buffer size to a lower value than what was chosen. If
399          * we try to allocate buffers of this size, it fails. Thus, forcibly
400          * use a larger buffer size. */
401         def->nBufferSize *= 2;
402     }
403
404  error:
405     return omx_error;
406 }
407
408
409 /*****************************************************************************
410  * UpdatePixelAspect: Update vlc pixel aspect based on the aspect reported on
411  * the omx port - NOTE: Broadcom specific
412  *****************************************************************************/
413 static OMX_ERRORTYPE UpdatePixelAspect(decoder_t *p_dec)
414 {
415     decoder_sys_t *p_sys = p_dec->p_sys;
416     OMX_CONFIG_POINTTYPE pixel_aspect;
417     OMX_INIT_STRUCTURE(pixel_aspect);
418     OMX_ERRORTYPE omx_err;
419
420     if (strncmp(p_sys->psz_component, "OMX.broadcom.", 13))
421         return OMX_ErrorNotImplemented;
422
423     pixel_aspect.nPortIndex = p_sys->out.i_port_index;
424     omx_err = OMX_GetParameter(p_sys->omx_handle,
425             OMX_IndexParamBrcmPixelAspectRatio, &pixel_aspect);
426     if (omx_err != OMX_ErrorNone) {
427         msg_Warn(p_dec, "Failed to retrieve aspect ratio");
428     } else {
429         p_dec->fmt_out.video.i_sar_num = pixel_aspect.nX;
430         p_dec->fmt_out.video.i_sar_den = pixel_aspect.nY;
431     }
432
433     return omx_err;
434 }
435
436 /*****************************************************************************
437  * AllocateBuffers: Allocate Omx buffers
438  *****************************************************************************/
439 static OMX_ERRORTYPE AllocateBuffers(decoder_t *p_dec, OmxPort *p_port)
440 {
441     decoder_sys_t *p_sys = p_dec->p_sys;
442     OMX_ERRORTYPE omx_error = OMX_ErrorUndefined;
443     OMX_PARAM_PORTDEFINITIONTYPE *def = &p_port->definition;
444     unsigned int i = 0;
445
446     OMX_DBG( "AllocateBuffers(%d)", def->eDir );
447
448     p_port->i_buffers = p_port->definition.nBufferCountActual;
449
450     p_port->pp_buffers = calloc(p_port->i_buffers, sizeof(OMX_BUFFERHEADERTYPE*));
451     if( !p_port->pp_buffers )
452     {
453         p_port->i_buffers = 0;
454         return OMX_ErrorInsufficientResources;
455     }
456
457     for(i = 0; i < p_port->i_buffers; i++)
458     {
459 #if 0
460 #define ALIGN(x,BLOCKLIGN) (((x) + BLOCKLIGN - 1) & ~(BLOCKLIGN - 1))
461         char *p_buf = malloc(p_port->definition.nBufferSize +
462                              p_port->definition.nBufferAlignment);
463         p_port->pp_buffers[i] = (void *)ALIGN((uintptr_t)p_buf, p_port->definition.nBufferAlignment);
464 #endif
465
466         if( p_port->p_hwbuf )
467         {
468             omx_error =
469                 OMX_UseBuffer( p_sys->omx_handle, &p_port->pp_buffers[i],
470                                p_port->i_port_index, 0,
471                                p_port->definition.nBufferSize,
472                                p_port->p_hwbuf->pp_handles[i] );
473             OMX_DBG( "OMX_UseBuffer(%d) %p, %p", def->eDir,
474                      p_port->pp_buffers[i], p_port->p_hwbuf->pp_handles[i] );
475         }
476         else if( p_port->b_direct )
477         {
478             omx_error =
479                 OMX_UseBuffer( p_sys->omx_handle, &p_port->pp_buffers[i],
480                                p_port->i_port_index, 0,
481                                p_port->definition.nBufferSize, (void*)1);
482             OMX_DBG( "OMX_UseBuffer(%d) %p, %p", def->eDir,
483                      p_port->pp_buffers[i], p_port->pp_buffers[i]->pBuffer );
484         }
485         else
486         {
487             omx_error =
488                 OMX_AllocateBuffer( p_sys->omx_handle, &p_port->pp_buffers[i],
489                                     p_port->i_port_index, 0,
490                                     p_port->definition.nBufferSize);
491             OMX_DBG( "OMX_AllocateBuffer(%d) %p, %p", def->eDir,
492                      p_port->pp_buffers[i], p_port->pp_buffers[i]->pBuffer );
493         }
494
495         if(omx_error != OMX_ErrorNone)
496         {
497             p_port->i_buffers = i;
498             break;
499         }
500         if( !p_port->p_hwbuf )
501             OMX_FIFO_PUT(&p_port->fifo, p_port->pp_buffers[i]);
502     }
503
504     CHECK_ERROR(omx_error, "AllocateBuffers failed (%x, %i)",
505                 omx_error, (int)p_port->i_port_index );
506
507
508     OMX_DBG( "AllocateBuffers(%d)::done", def->eDir );
509 error:
510     return omx_error;
511 }
512
513 /*****************************************************************************
514  * FreeBuffers: Free Omx buffers
515  *****************************************************************************/
516 static OMX_ERRORTYPE FreeBuffers(decoder_t *p_dec, OmxPort *p_port)
517 {
518     OMX_PARAM_PORTDEFINITIONTYPE *def = &p_port->definition;
519     OMX_ERRORTYPE omx_error = OMX_ErrorNone;
520     OMX_BUFFERHEADERTYPE *p_buffer;
521     unsigned int i, i_wait_buffers;
522
523     /* Normally, all buffers are in the port fifo, or given to the codec that
524      * will return them when disabling the port or changing state, therefore we
525      * normally wait for all buffers. For IOMX direct rendering (HwBuffer),
526      * only a few buffers are given to the codec at a time, thus we can only
527      * wait for that many buffers. And after that, we can still free all OMX
528      * buffers since we either got some of them returned via OMX_FIFO_GET, or
529      * never passed them to the codec at all. */
530     if( p_port->p_hwbuf )
531         i_wait_buffers = p_port->p_hwbuf->i_owned;
532     else
533         i_wait_buffers = p_port->i_buffers;
534
535     OMX_DBG( "FreeBuffers(%d), waiting for %u buffers", def->eDir,
536              i_wait_buffers);
537
538     for(i = 0; i < i_wait_buffers; i++)
539     {
540         OMX_FIFO_GET(&p_port->fifo, p_buffer);
541         if (p_buffer->nFlags & SENTINEL_FLAG) {
542             free(p_buffer);
543             i--;
544             continue;
545         }
546     }
547
548     for(i = 0; i < p_port->i_buffers; i++)
549     {
550         p_buffer = p_port->pp_buffers[i];
551         if( p_buffer )
552         {
553             if (p_buffer->pAppPrivate != NULL)
554                 decoder_DeletePicture( p_dec, p_buffer->pAppPrivate );
555
556             omx_error = OMX_FreeBuffer( p_port->omx_handle,
557                                         p_port->i_port_index, p_buffer );
558             OMX_DBG( "OMX_FreeBuffer(%d) %p, %p", def->eDir,
559                      p_buffer, p_buffer->pBuffer );
560
561             if(omx_error != OMX_ErrorNone) break;
562         }
563     }
564
565     if( omx_error != OMX_ErrorNone )
566        msg_Err( p_dec, "OMX_FreeBuffer failed (%x, %i, %i)",
567                 omx_error, (int)p_port->i_port_index, i );
568
569     p_port->i_buffers = 0;
570     free( p_port->pp_buffers );
571     p_port->pp_buffers = NULL;
572
573     OMX_DBG( "FreeBuffers(%d)::done", def->eDir );
574
575     return omx_error;
576 }
577
578 /*****************************************************************************
579  * GetPortDefinition: set vlc format based on the definition of the omx port
580  *****************************************************************************/
581 static OMX_ERRORTYPE GetPortDefinition(decoder_t *p_dec, OmxPort *p_port,
582                                        es_format_t *p_fmt)
583 {
584     decoder_sys_t *p_sys = p_dec->p_sys;
585     OMX_PARAM_PORTDEFINITIONTYPE *def = &p_port->definition;
586     OMX_ERRORTYPE omx_error;
587     OMX_CONFIG_RECTTYPE crop_rect;
588
589     omx_error = OMX_GetParameter(p_port->omx_handle,
590                                  OMX_IndexParamPortDefinition, def);
591     CHECK_ERROR(omx_error, "OMX_GetParameter failed (%x : %s)",
592                 omx_error, ErrorToString(omx_error));
593
594     switch(p_fmt->i_cat)
595     {
596     case VIDEO_ES:
597         p_fmt->video.i_width = def->format.video.nFrameWidth;
598         p_fmt->video.i_visible_width = def->format.video.nFrameWidth;
599         p_fmt->video.i_height = def->format.video.nFrameHeight;
600         p_fmt->video.i_visible_height = def->format.video.nFrameHeight;
601         p_fmt->video.i_frame_rate = p_dec->fmt_in.video.i_frame_rate;
602         p_fmt->video.i_frame_rate_base = p_dec->fmt_in.video.i_frame_rate_base;
603
604         OMX_INIT_STRUCTURE(crop_rect);
605         crop_rect.nPortIndex = def->nPortIndex;
606         omx_error = OMX_GetConfig(p_port->omx_handle, OMX_IndexConfigCommonOutputCrop, &crop_rect);
607         if (omx_error == OMX_ErrorNone)
608         {
609             if (!def->format.video.nSliceHeight)
610                 def->format.video.nSliceHeight = def->format.video.nFrameHeight;
611             if (!def->format.video.nStride)
612                 def->format.video.nStride = def->format.video.nFrameWidth;
613             p_fmt->video.i_width = crop_rect.nWidth;
614             p_fmt->video.i_visible_width = crop_rect.nWidth;
615             p_fmt->video.i_height = crop_rect.nHeight;
616             p_fmt->video.i_visible_height = crop_rect.nHeight;
617             if (def->format.video.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar)
618                 def->format.video.nSliceHeight -= crop_rect.nTop/2;
619
620             if( p_port->p_hwbuf )
621                 HwBuffer_SetCrop( p_dec, p_port, &crop_rect );
622         }
623         else
624         {
625             /* Don't pass the error back to the caller, this isn't mandatory */
626             omx_error = OMX_ErrorNone;
627         }
628
629         if( p_port->p_hwbuf )
630         {
631             UpdatePixelAspect(p_dec);
632             break;
633         }
634         /* Hack: Nexus One (stock firmware with binary OMX driver blob)
635          * claims to output 420Planar even though it in in practice is
636          * NV21. */
637         if(def->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar &&
638            !strncmp(p_sys->psz_component, "OMX.qcom.video.decoder",
639                     strlen("OMX.qcom.video.decoder")))
640             def->format.video.eColorFormat = OMX_QCOM_COLOR_FormatYVU420SemiPlanar;
641
642         if (IgnoreOmxDecoderPadding(p_sys->psz_component)) {
643             def->format.video.nSliceHeight = 0;
644             def->format.video.nStride = p_fmt->video.i_width;
645         }
646
647         if(!GetVlcVideoFormat( def->format.video.eCompressionFormat,
648                                &p_fmt->i_codec, 0 ) )
649         {
650             if( !GetVlcChromaFormat( def->format.video.eColorFormat,
651                                      &p_fmt->i_codec, 0 ) )
652             {
653                 omx_error = OMX_ErrorNotImplemented;
654                 CHECK_ERROR(omx_error, "OMX color format %i not supported",
655                             (int)def->format.video.eColorFormat );
656             }
657             GetVlcChromaSizes( p_fmt->i_codec,
658                                def->format.video.nFrameWidth,
659                                def->format.video.nFrameHeight,
660                                &p_port->i_frame_size, &p_port->i_frame_stride,
661                                &p_port->i_frame_stride_chroma_div );
662         }
663         if(p_port->i_frame_size > def->nBufferSize)
664             def->nBufferSize = p_port->i_frame_size;
665         p_port->i_frame_size = def->nBufferSize;
666 #if 0
667         if((int)p_port->i_frame_stride > def->format.video.nStride)
668             def->format.video.nStride = p_port->i_frame_stride;
669 #endif
670         p_port->i_frame_stride = def->format.video.nStride;
671         UpdatePixelAspect(p_dec);
672         break;
673
674     case AUDIO_ES:
675         if( !OmxToVlcAudioFormat( def->format.audio.eEncoding,
676                                 &p_fmt->i_codec, 0 ) )
677         {
678             omx_error = OMX_ErrorNotImplemented;
679             CHECK_ERROR(omx_error, "OMX audio format %i not supported",
680                         (int)def->format.audio.eEncoding );
681         }
682
683         omx_error = GetAudioParameters(p_port->omx_handle,
684                                        &p_port->format_param, def->nPortIndex,
685                                        def->format.audio.eEncoding,
686                                        &p_fmt->audio.i_channels,
687                                        &p_fmt->audio.i_rate,
688                                        &p_fmt->i_bitrate,
689                                        &p_fmt->audio.i_bitspersample,
690                                        &p_fmt->audio.i_blockalign);
691         CHECK_ERROR(omx_error, "GetAudioParameters failed (%x : %s)",
692                     omx_error, ErrorToString(omx_error));
693
694         if(p_fmt->audio.i_channels < 9)
695         {
696             static const int pi_channels_maps[9] =
697             {
698                 0, AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
699                 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
700                 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
701                 | AOUT_CHAN_REARRIGHT,
702                 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
703                 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
704                 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
705                 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
706                 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
707                 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT
708                 | AOUT_CHAN_MIDDLERIGHT,
709                 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
710                 | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
711                 | AOUT_CHAN_LFE
712             };
713             p_fmt->audio.i_physical_channels =
714                 p_fmt->audio.i_original_channels =
715                     pi_channels_maps[p_fmt->audio.i_channels];
716         }
717
718         date_Init( &p_dec->p_sys->end_date, p_fmt->audio.i_rate, 1 );
719
720         break;
721
722     default: return OMX_ErrorNotImplemented;
723     }
724
725  error:
726     return omx_error;
727 }
728
729 /*****************************************************************************
730  * DeinitialiseComponent: Deinitialise and unload an OMX component
731  *****************************************************************************/
732 static OMX_ERRORTYPE DeinitialiseComponent(decoder_t *p_dec,
733                                            OMX_HANDLETYPE omx_handle)
734 {
735     decoder_sys_t *p_sys = p_dec->p_sys;
736     OMX_BUFFERHEADERTYPE *p_buffer;
737     OMX_ERRORTYPE omx_error;
738     OMX_STATETYPE state;
739     unsigned int i;
740
741     if(!omx_handle) return OMX_ErrorNone;
742
743     omx_error = OMX_GetState(omx_handle, &state);
744     CHECK_ERROR(omx_error, "OMX_GetState failed (%x)", omx_error );
745
746     if( p_sys->out.p_hwbuf && HwBuffer_Stop( p_dec, &p_sys->out ) != 0 )
747         msg_Warn( p_dec, "HwBuffer_Stop failed" );
748
749     if(state == OMX_StateExecuting)
750     {
751         omx_error = OMX_SendCommand( omx_handle, OMX_CommandStateSet,
752                                      OMX_StateIdle, 0 );
753         CHECK_ERROR(omx_error, "OMX_CommandStateSet Idle failed (%x)", omx_error );
754         while (1) {
755             OMX_U32 cmd, state;
756             omx_error = WaitForSpecificOmxEvent(&p_sys->event_queue, OMX_EventCmdComplete, &cmd, &state, 0);
757             CHECK_ERROR(omx_error, "Wait for Idle failed (%x)", omx_error );
758             // The event queue can contain other OMX_EventCmdComplete items,
759             // such as for OMX_CommandFlush
760             if (cmd == OMX_CommandStateSet && state == OMX_StateIdle)
761                 break;
762         }
763     }
764
765     omx_error = OMX_GetState(omx_handle, &state);
766     CHECK_ERROR(omx_error, "OMX_GetState failed (%x)", omx_error );
767
768     if(state == OMX_StateIdle)
769     {
770         omx_error = OMX_SendCommand( omx_handle, OMX_CommandStateSet,
771                                      OMX_StateLoaded, 0 );
772         CHECK_ERROR(omx_error, "OMX_CommandStateSet Loaded failed (%x)", omx_error );
773
774         for(i = 0; i < p_sys->ports; i++)
775         {
776             OmxPort *p_port = &p_sys->p_ports[i];
777
778             omx_error = FreeBuffers( p_dec, p_port );
779             CHECK_ERROR(omx_error, "FreeBuffers failed (%x, %i)",
780                         omx_error, (int)p_port->i_port_index );
781             if( p_port->p_hwbuf )
782             {
783                 HwBuffer_FreeBuffers( p_dec, p_port );
784                 HwBuffer_Join( p_dec, p_port );
785             }
786         }
787
788         omx_error = WaitForSpecificOmxEvent(&p_sys->event_queue, OMX_EventCmdComplete, 0, 0, 0);
789         CHECK_ERROR(omx_error, "Wait for Loaded failed (%x)", omx_error );
790     }
791
792  error:
793     for(i = 0; i < p_sys->ports; i++)
794     {
795         OmxPort *p_port = &p_sys->p_ports[i];
796         free(p_port->pp_buffers);
797         p_port->pp_buffers = 0;
798
799         while (1) {
800             OMX_FIFO_PEEK(&p_port->fifo, p_buffer);
801             if (!p_buffer) break;
802
803             OMX_FIFO_GET(&p_port->fifo, p_buffer);
804             if (p_buffer->nFlags & SENTINEL_FLAG) {
805                 free(p_buffer);
806                 continue;
807             }
808             msg_Warn( p_dec, "Stray buffer left in fifo, %p", p_buffer );
809         }
810         HwBuffer_Destroy( p_dec, p_port );
811     }
812     omx_error = pf_free_handle( omx_handle );
813     return omx_error;
814 }
815
816 /*****************************************************************************
817  * InitialiseComponent: Load and initialise an OMX component
818  *****************************************************************************/
819 static OMX_ERRORTYPE InitialiseComponent(decoder_t *p_dec,
820     OMX_STRING psz_component, OMX_HANDLETYPE *p_handle)
821 {
822     static OMX_CALLBACKTYPE callbacks =
823         { OmxEventHandler, OmxEmptyBufferDone, OmxFillBufferDone };
824     decoder_sys_t *p_sys = p_dec->p_sys;
825     OMX_HANDLETYPE omx_handle;
826     OMX_ERRORTYPE omx_error;
827     unsigned int i;
828     OMX_U8 psz_role[OMX_MAX_STRINGNAME_SIZE];
829     OMX_PARAM_COMPONENTROLETYPE role;
830     OMX_PARAM_PORTDEFINITIONTYPE definition;
831     OMX_PORT_PARAM_TYPE param;
832
833     /* Load component */
834     omx_error = pf_get_handle( &omx_handle, psz_component, p_dec, &callbacks );
835     if(omx_error != OMX_ErrorNone)
836     {
837         msg_Warn( p_dec, "OMX_GetHandle(%s) failed (%x: %s)", psz_component,
838                   omx_error, ErrorToString(omx_error) );
839         return omx_error;
840     }
841     strncpy(p_sys->psz_component, psz_component, OMX_MAX_STRINGNAME_SIZE-1);
842
843     omx_error = OMX_ComponentRoleEnum(omx_handle, psz_role, 0);
844     if(omx_error == OMX_ErrorNone)
845         msg_Dbg(p_dec, "loaded component %s of role %s", psz_component, psz_role);
846     else
847         msg_Dbg(p_dec, "loaded component %s", psz_component);
848     PrintOmx(p_dec, omx_handle, OMX_ALL);
849
850     /* Set component role */
851     OMX_INIT_STRUCTURE(role);
852     strcpy((char*)role.cRole,
853            GetOmxRole(p_sys->b_enc ? p_dec->fmt_out.i_codec : p_dec->fmt_in.i_codec,
854                       p_dec->fmt_in.i_cat, p_sys->b_enc));
855
856     omx_error = OMX_SetParameter(omx_handle, OMX_IndexParamStandardComponentRole,
857                                  &role);
858     omx_error = OMX_GetParameter(omx_handle, OMX_IndexParamStandardComponentRole,
859                                  &role);
860     if(omx_error == OMX_ErrorNone)
861         msg_Dbg(p_dec, "component standard role set to %s", role.cRole);
862
863     /* Find the input / output ports */
864     OMX_INIT_STRUCTURE(param);
865     OMX_INIT_STRUCTURE(definition);
866     omx_error = OMX_GetParameter(omx_handle, p_dec->fmt_in.i_cat == VIDEO_ES ?
867                                  OMX_IndexParamVideoInit : OMX_IndexParamAudioInit, &param);
868     if(omx_error != OMX_ErrorNone) {
869 #ifdef __ANDROID__
870         param.nPorts = 2;
871         param.nStartPortNumber = 0;
872 #else
873         param.nPorts = 0;
874 #endif
875     }
876
877     for(i = 0; i < param.nPorts; i++)
878     {
879         OmxPort *p_port;
880
881         /* Get port definition */
882         definition.nPortIndex = param.nStartPortNumber + i;
883         omx_error = OMX_GetParameter(omx_handle, OMX_IndexParamPortDefinition,
884                                      &definition);
885         if(omx_error != OMX_ErrorNone) continue;
886
887         if(definition.eDir == OMX_DirInput) p_port = &p_sys->in;
888         else  p_port = &p_sys->out;
889
890         p_port->b_valid = true;
891         p_port->i_port_index = definition.nPortIndex;
892         p_port->definition = definition;
893         p_port->omx_handle = omx_handle;
894         HwBuffer_Init( p_dec, p_port );
895     }
896
897     if(!p_sys->in.b_valid || !p_sys->out.b_valid)
898     {
899         omx_error = OMX_ErrorInvalidComponent;
900         CHECK_ERROR(omx_error, "couldn't find an input and output port");
901     }
902
903     if( !p_sys->out.p_hwbuf && !strncmp(p_sys->psz_component, "OMX.SEC.", 8) &&
904        p_dec->fmt_in.i_cat == VIDEO_ES )
905     {
906         OMX_INDEXTYPE index;
907         omx_error = OMX_GetExtensionIndex(omx_handle, (OMX_STRING) "OMX.SEC.index.ThumbnailMode", &index);
908         if(omx_error == OMX_ErrorNone)
909         {
910             OMX_BOOL enable = OMX_TRUE;
911             omx_error = OMX_SetConfig(omx_handle, index, &enable);
912             CHECK_ERROR(omx_error, "Unable to set ThumbnailMode");
913         } else {
914             OMX_BOOL enable = OMX_TRUE;
915             /* Needed on Samsung Galaxy S II */
916             omx_error = OMX_SetConfig(omx_handle, OMX_IndexVendorSetYUV420pMode, &enable);
917             if (omx_error == OMX_ErrorNone)
918                 msg_Dbg(p_dec, "Set OMX_IndexVendorSetYUV420pMode successfully");
919             else
920                 msg_Dbg(p_dec, "Unable to set OMX_IndexVendorSetYUV420pMode: %x", omx_error);
921         }
922     }
923
924     if(!strncmp(p_sys->psz_component, "OMX.broadcom.", 13))
925     {
926         OMX_CONFIG_REQUESTCALLBACKTYPE notifications;
927         OMX_INIT_STRUCTURE(notifications);
928
929         notifications.nPortIndex = p_sys->out.i_port_index;
930         notifications.nIndex = OMX_IndexParamBrcmPixelAspectRatio;
931         notifications.bEnable = OMX_TRUE;
932
933         omx_error = OMX_SetParameter(omx_handle,
934                 OMX_IndexConfigRequestCallback, &notifications);
935         if (omx_error == OMX_ErrorNone) {
936             msg_Dbg(p_dec, "Enabled aspect ratio notifications");
937             p_sys->b_aspect_ratio_handled = true;
938         } else
939             msg_Dbg(p_dec, "Could not enable aspect ratio notifications");
940     }
941
942     /* Set port definitions */
943     for(i = 0; i < p_sys->ports; i++)
944     {
945         omx_error = SetPortDefinition(p_dec, &p_sys->p_ports[i],
946                                       p_sys->p_ports[i].p_fmt);
947         if(omx_error != OMX_ErrorNone) goto error;
948     }
949
950     if(!strncmp(p_sys->psz_component, "OMX.broadcom.", 13) &&
951         p_sys->in.p_fmt->i_codec == VLC_CODEC_H264)
952     {
953         OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE concanParam;
954         OMX_INIT_STRUCTURE(concanParam);
955         concanParam.bStartWithValidFrame = OMX_FALSE;
956
957         omx_error = OMX_SetParameter(omx_handle,
958                 OMX_IndexParamBrcmVideoDecodeErrorConcealment, &concanParam);
959         if (omx_error == OMX_ErrorNone)
960             msg_Dbg(p_dec, "StartWithValidFrame disabled.");
961         else
962             msg_Dbg(p_dec, "Could not disable StartWithValidFrame.");
963     }
964
965     /* Allocate our array for the omx buffers and enable ports */
966     for(i = 0; i < p_sys->ports; i++)
967     {
968         OmxPort *p_port = &p_sys->p_ports[i];
969
970         /* Enable port */
971         if(!p_port->definition.bEnabled)
972         {
973             omx_error = OMX_SendCommand( omx_handle, OMX_CommandPortEnable,
974                                          p_port->i_port_index, NULL);
975             CHECK_ERROR(omx_error, "OMX_CommandPortEnable on %i failed (%x)",
976                         (int)p_port->i_port_index, omx_error );
977             omx_error = WaitForSpecificOmxEvent(&p_sys->event_queue, OMX_EventCmdComplete, 0, 0, 0);
978             CHECK_ERROR(omx_error, "Wait for PortEnable on %i failed (%x)",
979                         (int)p_port->i_port_index, omx_error );
980         }
981     }
982
983     *p_handle = omx_handle;
984     return OMX_ErrorNone;
985
986  error:
987     DeinitialiseComponent(p_dec, omx_handle);
988     *p_handle = 0;
989     return omx_error;
990 }
991
992 /*****************************************************************************
993  * OpenDecoder: Create the decoder instance
994  *****************************************************************************/
995 static int OpenDecoder( vlc_object_t *p_this )
996 {
997     decoder_t *p_dec = (decoder_t*)p_this;
998     int status;
999
1000 #ifdef __ANDROID__
1001     if( p_dec->fmt_in.i_cat == AUDIO_ES )
1002         return VLC_EGENERIC;
1003 #endif
1004
1005     if( 0 || !GetOmxRole(p_dec->fmt_in.i_codec, p_dec->fmt_in.i_cat, false) )
1006         return VLC_EGENERIC;
1007
1008     status = OpenGeneric( p_this, false );
1009     if(status != VLC_SUCCESS) return status;
1010
1011     p_dec->pf_decode_video = DecodeVideo;
1012     p_dec->pf_decode_audio = DecodeAudio;
1013
1014     return VLC_SUCCESS;
1015 }
1016
1017 /*****************************************************************************
1018  * OpenEncoder: Create the encoder instance
1019  *****************************************************************************/
1020 static int OpenEncoder( vlc_object_t *p_this )
1021 {
1022     encoder_t *p_enc = (encoder_t*)p_this;
1023     int status;
1024
1025     if( !GetOmxRole(p_enc->fmt_out.i_codec, p_enc->fmt_in.i_cat, true) )
1026         return VLC_EGENERIC;
1027
1028     status = OpenGeneric( p_this, true );
1029     if(status != VLC_SUCCESS) return status;
1030
1031     p_enc->pf_encode_video = EncodeVideo;
1032
1033     return VLC_SUCCESS;
1034 }
1035
1036 /*****************************************************************************
1037  * OpenGeneric: Create the generic decoder/encoder instance
1038  *****************************************************************************/
1039 static int OpenGeneric( vlc_object_t *p_this, bool b_encode )
1040 {
1041     decoder_t *p_dec = (decoder_t*)p_this;
1042     decoder_sys_t *p_sys;
1043     OMX_ERRORTYPE omx_error;
1044     OMX_BUFFERHEADERTYPE *p_header;
1045     unsigned int i;
1046
1047     if (InitOmxCore(p_this) != VLC_SUCCESS) {
1048         return VLC_EGENERIC;
1049     }
1050
1051     /* Allocate the memory needed to store the decoder's structure */
1052     if( ( p_dec->p_sys = p_sys = calloc( 1, sizeof(*p_sys)) ) == NULL )
1053     {
1054         DeinitOmxCore();
1055         return VLC_ENOMEM;
1056     }
1057
1058     /* Initialise the thread properties */
1059     if(!b_encode)
1060     {
1061         p_dec->fmt_out.i_cat = p_dec->fmt_in.i_cat;
1062         p_dec->fmt_out.video = p_dec->fmt_in.video;
1063         p_dec->fmt_out.audio = p_dec->fmt_in.audio;
1064         p_dec->fmt_out.i_codec = 0;
1065
1066         /* set default aspect of 1, if parser did not set it */
1067         if (p_dec->fmt_out.video.i_sar_num == 0)
1068             p_dec->fmt_out.video.i_sar_num = 1;
1069         if (p_dec->fmt_out.video.i_sar_den == 0)
1070             p_dec->fmt_out.video.i_sar_den = 1;
1071     }
1072     p_sys->b_enc = b_encode;
1073     InitOmxEventQueue(&p_sys->event_queue);
1074     OMX_FIFO_INIT (&p_sys->in.fifo, pOutputPortPrivate );
1075     p_sys->in.b_direct = false;
1076     p_sys->in.b_flushed = true;
1077     p_sys->in.p_fmt = &p_dec->fmt_in;
1078     OMX_FIFO_INIT (&p_sys->out.fifo, pInputPortPrivate );
1079 #if defined(USE_IOMX)
1080     p_sys->out.b_direct = jni_IsVideoPlayerActivityCreated() && var_InheritBool(p_dec, CFG_PREFIX "dr");
1081 #else
1082     p_sys->out.b_direct = false;
1083 #endif
1084     p_sys->out.b_flushed = true;
1085     p_sys->out.p_fmt = &p_dec->fmt_out;
1086     p_sys->ports = 2;
1087     p_sys->p_ports = &p_sys->in;
1088     p_sys->b_use_pts = 1;
1089
1090     msg_Dbg(p_dec, "fmt in:%4.4s, out: %4.4s", (char *)&p_dec->fmt_in.i_codec,
1091             (char *)&p_dec->fmt_out.i_codec);
1092
1093     /* Enumerate components and build a list of the one we want to try */
1094     p_sys->components =
1095         CreateComponentsList(p_this,
1096              GetOmxRole(p_sys->b_enc ? p_dec->fmt_out.i_codec :
1097                         p_dec->fmt_in.i_codec, p_dec->fmt_in.i_cat,
1098                         p_sys->b_enc), p_sys->ppsz_components);
1099     if( !p_sys->components )
1100     {
1101         msg_Warn( p_this, "couldn't find an omx component for codec %4.4s",
1102                   (char *)&p_dec->fmt_in.i_codec );
1103         CloseGeneric(p_this);
1104         return VLC_EGENERIC;
1105     }
1106
1107     /* Try to load and initialise a component */
1108     omx_error = OMX_ErrorUndefined;
1109     for(i = 0; i < p_sys->components; i++)
1110     {
1111 #ifdef __ANDROID__
1112         /* ignore OpenCore software codecs */
1113         if (!strncmp(p_sys->ppsz_components[i], "OMX.PV.", 7))
1114             continue;
1115         /* The same sw codecs, renamed in ICS (perhaps also in honeycomb) */
1116         if (!strncmp(p_sys->ppsz_components[i], "OMX.google.", 11))
1117             continue;
1118         /* This one has been seen on HTC One V - it behaves like it works,
1119          * but FillBufferDone returns buffers filled with 0 bytes. The One V
1120          * has got a working OMX.qcom.video.decoder.avc instead though. */
1121         if (!strncmp(p_sys->ppsz_components[i], "OMX.ARICENT.", 12))
1122             continue;
1123         /* Codecs with DRM, that don't output plain YUV data but only
1124          * support direct rendering where the output can't be intercepted. */
1125         if (strstr(p_sys->ppsz_components[i], ".secure"))
1126             continue;
1127         /* Use VC1 decoder for WMV3 for now */
1128         if (!strcmp(p_sys->ppsz_components[i], "OMX.SEC.WMV.Decoder"))
1129             continue;
1130         /* This decoder does work, but has an insane latency (leading to errors
1131          * about "main audio output playback way too late" and dropped frames).
1132          * At least Samsung Galaxy S III (where this decoder is present) has
1133          * got another one, OMX.SEC.mp3.dec, that works well and has a
1134          * sensible latency. (Also, even if that one isn't found, in general,
1135          * using SW codecs is usually more than fast enough for MP3.) */
1136         if (!strcmp(p_sys->ppsz_components[i], "OMX.SEC.MP3.Decoder"))
1137             continue;
1138         /* This codec should be able to handle both VC1 and WMV3, but
1139          * for VC1 it doesn't output any buffers at all (in the way we use
1140          * it) and for WMV3 it outputs plain black buffers. Thus ignore
1141          * it until we can make it work properly. */
1142         if (!strcmp(p_sys->ppsz_components[i], "OMX.Nvidia.vc1.decode"))
1143             continue;
1144 #endif
1145         omx_error = InitialiseComponent(p_dec, p_sys->ppsz_components[i],
1146                                         &p_sys->omx_handle);
1147         if(omx_error == OMX_ErrorNone) break;
1148     }
1149     CHECK_ERROR(omx_error, "no component could be initialised" );
1150
1151     /* Move component to Idle then Executing state */
1152     OMX_SendCommand( p_sys->omx_handle, OMX_CommandStateSet, OMX_StateIdle, 0 );
1153     CHECK_ERROR(omx_error, "OMX_CommandStateSet Idle failed (%x)", omx_error );
1154
1155     /* Allocate omx buffers */
1156     for(i = 0; i < p_sys->ports; i++)
1157     {
1158         OmxPort *p_port = &p_sys->p_ports[i];
1159         if( p_port->p_hwbuf )
1160         {
1161             if( HwBuffer_AllocateBuffers( p_dec, p_port ) != 0 )
1162             {
1163                 omx_error = OMX_ErrorInsufficientResources;
1164                 goto error;
1165             }
1166         }
1167         omx_error = AllocateBuffers( p_dec, p_port );
1168         CHECK_ERROR(omx_error, "AllocateBuffers failed (%x, %i)",
1169                     omx_error, (int)p_port->i_port_index );
1170     }
1171
1172     omx_error = WaitForSpecificOmxEvent(&p_sys->event_queue, OMX_EventCmdComplete, 0, 0, 0);
1173     CHECK_ERROR(omx_error, "Wait for Idle failed (%x)", omx_error );
1174
1175     omx_error = OMX_SendCommand( p_sys->omx_handle, OMX_CommandStateSet,
1176                                  OMX_StateExecuting, 0);
1177     CHECK_ERROR(omx_error, "OMX_CommandStateSet Executing failed (%x)", omx_error );
1178     omx_error = WaitForSpecificOmxEvent(&p_sys->event_queue, OMX_EventCmdComplete, 0, 0, 0);
1179     CHECK_ERROR(omx_error, "Wait for Executing failed (%x)", omx_error );
1180
1181     if( p_sys->out.p_hwbuf && HwBuffer_Start( p_dec, &p_sys->out ) != 0 )
1182     {
1183         omx_error = OMX_ErrorUndefined;
1184         goto error;
1185     }
1186
1187     /* Send codec configuration data */
1188     if( p_dec->fmt_in.i_extra )
1189     {
1190         OMX_FIFO_GET(&p_sys->in.fifo, p_header);
1191         p_header->nFilledLen = p_dec->fmt_in.i_extra;
1192
1193         /* Convert H.264 NAL format to annex b */
1194         if( p_sys->i_nal_size_length && !p_sys->in.b_direct )
1195         {
1196             p_header->nFilledLen = 0;
1197             convert_sps_pps( p_dec, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra,
1198                              p_header->pBuffer, p_header->nAllocLen,
1199                              (uint32_t*) &p_header->nFilledLen, NULL );
1200         }
1201         else if( p_dec->fmt_in.i_codec == VLC_CODEC_HEVC && !p_sys->in.b_direct )
1202         {
1203             p_header->nFilledLen = 0;
1204             convert_hevc_nal_units( p_dec, p_dec->fmt_in.p_extra,
1205                                     p_dec->fmt_in.i_extra,
1206                                     p_header->pBuffer, p_header->nAllocLen,
1207                                     (uint32_t*) &p_header->nFilledLen,
1208                                     &p_sys->i_nal_size_length );
1209         }
1210         else if(p_sys->in.b_direct)
1211         {
1212             p_header->pOutputPortPrivate = p_header->pBuffer;
1213             p_header->pBuffer = p_dec->fmt_in.p_extra;
1214         }
1215         else if (p_dec->fmt_in.i_codec == VLC_CODEC_WMV3 &&
1216                  p_dec->fmt_in.i_extra >= 4 &&
1217                  p_header->nAllocLen >= 36)
1218         {
1219             int profile;
1220             // According to OMX IL 1.2.0 spec (4.3.33.2), the codec config
1221             // data for VC-1 Main/Simple (aka WMV3) is according to table 265
1222             // in the VC-1 spec. Most of the fields are just set with placeholders
1223             // (like framerate, hrd_buffer/rate).
1224             static const uint8_t wmv3seq[] = {
1225                 0xff, 0xff, 0xff, 0xc5, // numframes=ffffff, marker byte
1226                 0x04, 0x00, 0x00, 0x00, // marker byte
1227                 0x00, 0x00, 0x00, 0x00, // struct C, almost equal to p_extra
1228                 0x00, 0x00, 0x00, 0x00, // struct A, vert size
1229                 0x00, 0x00, 0x00, 0x00, // struct A, horiz size
1230                 0x0c, 0x00, 0x00, 0x00, // marker byte
1231                 0xff, 0xff, 0x00, 0x80, // struct B, level=4, cbr=0, hrd_buffer=ffff
1232                 0xff, 0xff, 0x00, 0x00, // struct B, hrd_rate=ffff
1233                 0xff, 0xff, 0xff, 0xff, // struct B, framerate=ffffffff
1234             };
1235             p_header->nFilledLen = sizeof(wmv3seq);
1236             memcpy(p_header->pBuffer, wmv3seq, p_header->nFilledLen);
1237             // Struct C - almost equal to the extradata
1238             memcpy(&p_header->pBuffer[8], p_dec->fmt_in.p_extra, 4);
1239             // Expand profile from the highest 2 bits to the highest 4 bits
1240             profile = p_header->pBuffer[8] >> 6;
1241             p_header->pBuffer[8] = (p_header->pBuffer[8] & 0x0f) | (profile << 4);
1242             // Fill in the height/width for struct A
1243             SetDWLE(&p_header->pBuffer[12], p_dec->fmt_in.video.i_height);
1244             SetDWLE(&p_header->pBuffer[16], p_dec->fmt_in.video.i_width);
1245         }
1246         else
1247         {
1248             if(p_header->nFilledLen > p_header->nAllocLen)
1249             {
1250                 msg_Dbg(p_dec, "buffer too small (%i,%i)", (int)p_header->nFilledLen,
1251                         (int)p_header->nAllocLen);
1252                 p_header->nFilledLen = p_header->nAllocLen;
1253             }
1254             memcpy(p_header->pBuffer, p_dec->fmt_in.p_extra, p_header->nFilledLen);
1255         }
1256
1257         p_header->nOffset = 0;
1258         p_header->nFlags = OMX_BUFFERFLAG_CODECCONFIG | OMX_BUFFERFLAG_ENDOFFRAME;
1259         msg_Dbg(p_dec, "sending codec config data %p, %p, %i", p_header,
1260                 p_header->pBuffer, (int)p_header->nFilledLen);
1261         OMX_EmptyThisBuffer(p_sys->omx_handle, p_header);
1262     }
1263
1264     /* Get back output port definition */
1265     omx_error = GetPortDefinition(p_dec, &p_sys->out, p_sys->out.p_fmt);
1266     if(omx_error != OMX_ErrorNone) goto error;
1267
1268     PrintOmx(p_dec, p_sys->omx_handle, p_dec->p_sys->in.i_port_index);
1269     PrintOmx(p_dec, p_sys->omx_handle, p_dec->p_sys->out.i_port_index);
1270
1271     if(p_sys->b_error) goto error;
1272
1273     p_dec->b_need_packetized = true;
1274
1275     if (!p_sys->b_use_pts)
1276         msg_Dbg( p_dec, "using dts timestamp mode for %s", p_sys->psz_component);
1277
1278     return VLC_SUCCESS;
1279
1280  error:
1281     CloseGeneric(p_this);
1282     return VLC_EGENERIC;
1283 }
1284
1285 /*****************************************************************************
1286  * PortReconfigure
1287  *****************************************************************************/
1288 static OMX_ERRORTYPE PortReconfigure(decoder_t *p_dec, OmxPort *p_port)
1289 {
1290     decoder_sys_t *p_sys = p_dec->p_sys;
1291     OMX_PARAM_PORTDEFINITIONTYPE definition;
1292     OMX_ERRORTYPE omx_error;
1293
1294     OMX_DBG( "PortReconfigure(%d)", p_port->definition.eDir );
1295
1296     /* Sanity checking */
1297     OMX_INIT_STRUCTURE(definition);
1298     definition.nPortIndex = p_port->i_port_index;
1299     omx_error = OMX_GetParameter(p_dec->p_sys->omx_handle, OMX_IndexParamPortDefinition,
1300                                  &definition);
1301     if(omx_error != OMX_ErrorNone || (p_dec->fmt_in.i_cat == VIDEO_ES &&
1302        (!definition.format.video.nFrameWidth ||
1303        !definition.format.video.nFrameHeight)) )
1304         return OMX_ErrorUndefined;
1305
1306     if( p_port->p_hwbuf && HwBuffer_Stop( p_dec, p_port ) != 0 )
1307         msg_Warn( p_dec, "HwBuffer_Stop failed" );
1308
1309     omx_error = OMX_SendCommand( p_sys->omx_handle, OMX_CommandPortDisable,
1310                                  p_port->i_port_index, NULL);
1311     CHECK_ERROR(omx_error, "OMX_CommandPortDisable on %i failed (%x)",
1312                 (int)p_port->i_port_index, omx_error );
1313
1314     omx_error = FreeBuffers( p_dec, p_port );
1315     CHECK_ERROR(omx_error, "FreeBuffers failed (%x, %i)",
1316                 omx_error, (int)p_port->i_port_index );
1317
1318     if( p_port->p_hwbuf )
1319     {
1320         HwBuffer_FreeBuffers( p_dec, p_port );
1321         HwBuffer_Join( p_dec, p_port );
1322     }
1323
1324     omx_error = WaitForSpecificOmxEvent(&p_sys->event_queue, OMX_EventCmdComplete, 0, 0, 0);
1325     CHECK_ERROR(omx_error, "Wait for PortDisable failed (%x)", omx_error );
1326
1327     /* Get the new port definition */
1328     omx_error = GetPortDefinition(p_dec, &p_sys->out, p_sys->out.p_fmt);
1329     if(omx_error != OMX_ErrorNone) goto error;
1330
1331     if( p_port->p_hwbuf )
1332     {
1333         if( HwBuffer_AllocateBuffers( p_dec, p_port ) != 0 )
1334         {
1335             omx_error = OMX_ErrorInsufficientResources;
1336             goto error;
1337         }
1338     }
1339     else if( p_dec->fmt_in.i_cat != AUDIO_ES )
1340     {
1341         /* Don't explicitly set the new parameters that we got with
1342          * OMX_GetParameter above when using audio codecs.
1343          * That struct hasn't been changed since, so there should be
1344          * no need to set it here, unless some codec expects the
1345          * SetParameter call as a trigger event for some part of
1346          * the reconfiguration.
1347          * This fixes using audio decoders on Samsung Galaxy S II,
1348          *
1349          * Only skipping this for audio codecs, to minimize the
1350          * change for current working configurations for video.
1351          */
1352         omx_error = OMX_SetParameter(p_dec->p_sys->omx_handle, OMX_IndexParamPortDefinition,
1353                                      &definition);
1354         CHECK_ERROR(omx_error, "OMX_SetParameter failed (%x : %s)",
1355                     omx_error, ErrorToString(omx_error));
1356     }
1357
1358     omx_error = OMX_SendCommand( p_sys->omx_handle, OMX_CommandPortEnable,
1359                                  p_port->i_port_index, NULL);
1360     CHECK_ERROR(omx_error, "OMX_CommandPortEnable on %i failed (%x)",
1361                 (int)p_port->i_port_index, omx_error );
1362
1363     omx_error = AllocateBuffers( p_dec, p_port );
1364     CHECK_ERROR(omx_error, "OMX_AllocateBuffers failed (%x, %i)",
1365                 omx_error, (int)p_port->i_port_index );
1366
1367     omx_error = WaitForSpecificOmxEvent(&p_sys->event_queue, OMX_EventCmdComplete, 0, 0, 0);
1368     CHECK_ERROR(omx_error, "Wait for PortEnable failed (%x)", omx_error );
1369
1370     if( p_port->p_hwbuf && HwBuffer_Start( p_dec, p_port ) != 0 )
1371     {
1372         omx_error = OMX_ErrorUndefined;
1373         goto error;
1374     }
1375
1376     PrintOmx(p_dec, p_sys->omx_handle, p_dec->p_sys->in.i_port_index);
1377     PrintOmx(p_dec, p_sys->omx_handle, p_dec->p_sys->out.i_port_index);
1378
1379     OMX_DBG( "PortReconfigure(%d)::done", p_port->definition.eDir );
1380  error:
1381     return omx_error;
1382 }
1383
1384 /*****************************************************************************
1385  * DecodeVideoOutput
1386  *****************************************************************************/
1387 static int DecodeVideoOutput( decoder_t *p_dec, OmxPort *p_port, picture_t **pp_pic )
1388 {
1389     VLC_UNUSED( p_dec );
1390     OMX_BUFFERHEADERTYPE *p_header;
1391     picture_t *p_pic = NULL, *p_next_pic;
1392     OMX_ERRORTYPE omx_error;
1393
1394     while(!p_pic)
1395     {
1396         OMX_FIFO_PEEK(&p_port->fifo, p_header);
1397         if(!p_header) break; /* No frame available */
1398
1399         if(p_port->b_update_def)
1400         {
1401             omx_error = GetPortDefinition(p_dec, p_port, p_port->p_fmt);
1402             p_port->b_update_def = 0;
1403             CHECK_ERROR(omx_error, "GetPortDefinition failed");
1404         }
1405
1406         if( p_port->p_hwbuf )
1407         {
1408             if( HwBuffer_GetPic( p_dec, p_port, &p_pic ) != 0 )
1409                 goto error;
1410             else
1411                 continue;
1412         }
1413
1414         if(p_header->nFilledLen)
1415         {
1416             p_pic = p_header->pAppPrivate;
1417             if(!p_pic)
1418             {
1419                 /* We're not in direct rendering mode.
1420                  * Get a new picture and copy the content */
1421                 p_pic = decoder_NewPicture( p_dec );
1422
1423                 if (p_pic)
1424                     CopyOmxPicture(p_port->definition.format.video.eColorFormat,
1425                                    p_pic, p_port->definition.format.video.nSliceHeight,
1426                                    p_port->i_frame_stride,
1427                                    p_header->pBuffer + p_header->nOffset,
1428                                    p_port->i_frame_stride_chroma_div, NULL);
1429             }
1430
1431             if (p_pic)
1432                 p_pic->date = FromOmxTicks(p_header->nTimeStamp);
1433             p_header->nFilledLen = 0;
1434             p_header->pAppPrivate = 0;
1435         }
1436
1437         /* Get a new picture */
1438         if(p_port->b_direct && !p_header->pAppPrivate)
1439         {
1440             p_next_pic = decoder_NewPicture( p_dec );
1441             if(!p_next_pic) break;
1442
1443             OMX_FIFO_GET(&p_port->fifo, p_header);
1444             p_header->pAppPrivate = p_next_pic;
1445             p_header->pInputPortPrivate = p_header->pBuffer;
1446             p_header->pBuffer = p_next_pic->p[0].p_pixels;
1447         }
1448         else
1449         {
1450             OMX_FIFO_GET(&p_port->fifo, p_header);
1451         }
1452         OMX_DBG( "FillThisBuffer %p, %p", p_header, p_header->pBuffer );
1453         OMX_FillThisBuffer(p_port->omx_handle, p_header);
1454     }
1455
1456     *pp_pic = p_pic;
1457     return 0;
1458 error:
1459     return -1;
1460 }
1461
1462 static int DecodeVideoInput( decoder_t *p_dec, OmxPort *p_port, block_t **pp_block,
1463                              unsigned int i_input_used, bool *p_reconfig )
1464 {
1465     decoder_sys_t *p_sys = p_dec->p_sys;
1466     OMX_BUFFERHEADERTYPE *p_header;
1467     struct H264ConvertState convert_state = { 0, 0 };
1468     block_t *p_block = *pp_block;
1469
1470     /* Send the input buffer to the component */
1471     OMX_FIFO_GET_TIMEOUT(&p_port->fifo, p_header, 10000);
1472
1473     if (p_header && p_header->nFlags & SENTINEL_FLAG) {
1474         free(p_header);
1475         *p_reconfig = true;
1476         return 0;
1477     }
1478     *p_reconfig = false;
1479
1480     if(p_header)
1481     {
1482         bool decode_more = false;
1483         p_header->nFilledLen = p_block->i_buffer - i_input_used;
1484         p_header->nOffset = 0;
1485         p_header->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
1486         if (p_sys->b_use_pts && p_block->i_pts)
1487             p_header->nTimeStamp = ToOmxTicks(p_block->i_pts);
1488         else
1489             p_header->nTimeStamp = ToOmxTicks(p_block->i_dts);
1490
1491         /* In direct mode we pass the input pointer as is.
1492          * Otherwise we memcopy the data */
1493         if(p_port->b_direct)
1494         {
1495             p_header->pOutputPortPrivate = p_header->pBuffer;
1496             p_header->pBuffer = p_block->p_buffer;
1497             p_header->pAppPrivate = p_block;
1498             i_input_used = p_header->nFilledLen;
1499         }
1500         else
1501         {
1502             if(p_header->nFilledLen > p_header->nAllocLen)
1503             {
1504                 p_header->nFilledLen = p_header->nAllocLen;
1505             }
1506             memcpy(p_header->pBuffer, p_block->p_buffer + i_input_used, p_header->nFilledLen);
1507             i_input_used += p_header->nFilledLen;
1508             if (i_input_used == p_block->i_buffer)
1509             {
1510                 block_Release(p_block);
1511             }
1512             else
1513             {
1514                 decode_more = true;
1515                 p_header->nFlags &= ~OMX_BUFFERFLAG_ENDOFFRAME;
1516             }
1517         }
1518
1519         /* Convert H.264 NAL format to annex b. Doesn't do anything if
1520          * i_nal_size_length == 0, which is the case for codecs other
1521          * than H.264 */
1522         convert_h264_to_annexb( p_header->pBuffer, p_header->nFilledLen,
1523                                 p_sys->i_nal_size_length, &convert_state );
1524         OMX_DBG( "EmptyThisBuffer %p, %p, %i, %"PRId64, p_header, p_header->pBuffer,
1525                  (int)p_header->nFilledLen, FromOmxTicks(p_header->nTimeStamp) );
1526         OMX_EmptyThisBuffer(p_port->omx_handle, p_header);
1527         p_port->b_flushed = false;
1528         if (decode_more)
1529             return DecodeVideoInput( p_dec, p_port, pp_block, i_input_used,
1530                                      p_reconfig );
1531         else
1532             *pp_block = NULL; /* Avoid being fed the same packet again */
1533     }
1534
1535     return 0;
1536 }
1537
1538 /*****************************************************************************
1539  * DecodeVideo: Called to decode one frame
1540  *****************************************************************************/
1541 static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
1542 {
1543     decoder_sys_t *p_sys = p_dec->p_sys;
1544     picture_t *p_pic = NULL;
1545     OMX_ERRORTYPE omx_error;
1546     unsigned int i;
1547     block_t *p_block;
1548
1549     if( !pp_block || !*pp_block )
1550         return NULL;
1551
1552     p_block = *pp_block;
1553
1554     /* Check for errors from codec */
1555     if(p_sys->b_error)
1556     {
1557         msg_Dbg(p_dec, "error during decoding");
1558         block_Release( p_block );
1559         return 0;
1560     }
1561
1562     if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
1563     {
1564         block_Release( p_block );
1565         if(!p_sys->in.b_flushed)
1566         {
1567             msg_Dbg(p_dec, "flushing");
1568             OMX_SendCommand( p_sys->omx_handle, OMX_CommandFlush,
1569                              p_sys->in.definition.nPortIndex, 0 );
1570         }
1571         p_sys->in.b_flushed = true;
1572         return NULL;
1573     }
1574
1575     /* Use the aspect ratio provided by the input (ie read from packetizer).
1576      * In case the we get aspect ratio info from the decoder (as in the
1577      * broadcom OMX implementation on RPi), don't let the packetizer values
1578      * override what the decoder says, if anything - otherwise always update
1579      * even if it already is set (since it can change within a stream). */
1580     if((p_dec->fmt_in.video.i_sar_num != 0 && p_dec->fmt_in.video.i_sar_den != 0) &&
1581        (p_dec->fmt_out.video.i_sar_num == 0 || p_dec->fmt_out.video.i_sar_den == 0 ||
1582              !p_sys->b_aspect_ratio_handled))
1583     {
1584         p_dec->fmt_out.video.i_sar_num = p_dec->fmt_in.video.i_sar_num;
1585         p_dec->fmt_out.video.i_sar_den = p_dec->fmt_in.video.i_sar_den;
1586     }
1587
1588     /* Take care of decoded frames first */
1589     if( DecodeVideoOutput( p_dec, &p_sys->out, &p_pic ) != 0 )
1590         goto error;
1591
1592     /* Loop as long as we haven't either got an input buffer (and cleared
1593      * *pp_block) or got an output picture */
1594     int max_polling_attempts = 100;
1595     int attempts = 0;
1596     while( *pp_block && !p_pic ) {
1597         bool b_reconfig = false;
1598
1599         if( DecodeVideoInput( p_dec, &p_sys->in, pp_block, 0, &b_reconfig ) != 0 )
1600             goto error;
1601
1602         /* If we don't have a p_pic from the first try. Try again */
1603         if( !b_reconfig && !p_pic &&
1604             DecodeVideoOutput( p_dec, &p_sys->out, &p_pic ) != 0 )
1605             goto error;
1606
1607         /* Handle the PortSettingsChanged events */
1608         for(i = 0; i < p_sys->ports; i++)
1609         {
1610             OmxPort *p_port = &p_sys->p_ports[i];
1611             if(p_port->b_reconfigure)
1612             {
1613                 omx_error = PortReconfigure(p_dec, p_port);
1614                 p_port->b_reconfigure = 0;
1615                 CHECK_ERROR(omx_error, "PortReconfigure failed");
1616             }
1617             if(p_port->b_update_def)
1618             {
1619                 omx_error = GetPortDefinition(p_dec, p_port, p_port->p_fmt);
1620                 p_port->b_update_def = 0;
1621                 CHECK_ERROR(omx_error, "GetPortDefinition failed");
1622             }
1623         }
1624
1625         attempts++;
1626         /* With opaque DR the output buffers are released by the
1627            vout therefore we implement a timeout for polling in
1628            order to avoid being indefinitely stalled in this loop, if
1629            playback is paused. */
1630         if( p_sys->out.p_hwbuf && attempts == max_polling_attempts ) {
1631 #ifdef USE_IOMX
1632             picture_t *invalid_picture = decoder_NewPicture(p_dec);
1633             if (invalid_picture) {
1634                 invalid_picture->date = VLC_TS_INVALID;
1635                 picture_sys_t *p_picsys = invalid_picture->p_sys;
1636                 p_picsys->pf_display_callback = NULL;
1637                 p_picsys->pf_unlock_callback = NULL;
1638                 p_picsys->p_dec = NULL;
1639                 p_picsys->i_index = -1;
1640                 p_picsys->b_valid = false;
1641             } else {
1642                 /* If we cannot return a picture we must free the
1643                    block since the decoder will proceed with the
1644                    next block. */
1645                 block_Release(p_block);
1646                 *pp_block = NULL;
1647             }
1648             return invalid_picture;
1649 #endif
1650         }
1651     }
1652
1653     return p_pic;
1654 error:
1655     p_sys->b_error = true;
1656     return NULL;
1657 }
1658
1659 /*****************************************************************************
1660  * DecodeAudio: Called to decode one frame
1661  *****************************************************************************/
1662 block_t *DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
1663 {
1664     decoder_sys_t *p_sys = p_dec->p_sys;
1665     block_t *p_buffer = NULL;
1666     OMX_BUFFERHEADERTYPE *p_header;
1667     OMX_ERRORTYPE omx_error;
1668     block_t *p_block;
1669     unsigned int i;
1670
1671     if( !pp_block || !*pp_block ) return NULL;
1672
1673     p_block = *pp_block;
1674
1675     /* Check for errors from codec */
1676     if(p_sys->b_error)
1677     {
1678         msg_Dbg(p_dec, "error during decoding");
1679         block_Release( p_block );
1680         return 0;
1681     }
1682
1683     if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
1684     {
1685         block_Release( p_block );
1686         date_Set( &p_sys->end_date, 0 );
1687         if(!p_sys->in.b_flushed)
1688         {
1689             msg_Dbg(p_dec, "flushing");
1690             OMX_SendCommand( p_sys->omx_handle, OMX_CommandFlush,
1691                              p_sys->in.definition.nPortIndex, 0 );
1692         }
1693         p_sys->in.b_flushed = true;
1694         return NULL;
1695     }
1696
1697     if( !date_Get( &p_sys->end_date ) )
1698     {
1699         if( !p_block->i_pts )
1700         {
1701             /* We've just started the stream, wait for the first PTS. */
1702             block_Release( p_block );
1703             return NULL;
1704         }
1705         date_Set( &p_sys->end_date, p_block->i_pts );
1706     }
1707
1708     /* Take care of decoded frames first */
1709     while(!p_buffer)
1710     {
1711         unsigned int i_samples = 0;
1712
1713         OMX_FIFO_PEEK(&p_sys->out.fifo, p_header);
1714         if(!p_header) break; /* No frame available */
1715
1716         if (p_sys->out.p_fmt->audio.i_channels)
1717             i_samples = p_header->nFilledLen / p_sys->out.p_fmt->audio.i_channels / 2;
1718         if(i_samples)
1719         {
1720             p_buffer = decoder_NewAudioBuffer( p_dec, i_samples );
1721             if( !p_buffer ) break; /* No audio buffer available */
1722
1723             memcpy( p_buffer->p_buffer, p_header->pBuffer, p_buffer->i_buffer );
1724             p_header->nFilledLen = 0;
1725
1726             int64_t timestamp = FromOmxTicks(p_header->nTimeStamp);
1727             if( timestamp != 0 &&
1728                 timestamp != date_Get( &p_sys->end_date ) )
1729                 date_Set( &p_sys->end_date, timestamp );
1730
1731             p_buffer->i_pts = date_Get( &p_sys->end_date );
1732             p_buffer->i_length = date_Increment( &p_sys->end_date, i_samples ) -
1733                 p_buffer->i_pts;
1734         }
1735
1736         OMX_DBG( "FillThisBuffer %p, %p", p_header, p_header->pBuffer );
1737         OMX_FIFO_GET(&p_sys->out.fifo, p_header);
1738         OMX_FillThisBuffer(p_sys->omx_handle, p_header);
1739     }
1740
1741
1742     /* Send the input buffer to the component */
1743     OMX_FIFO_GET_TIMEOUT(&p_sys->in.fifo, p_header, 200000);
1744
1745     if (p_header && p_header->nFlags & SENTINEL_FLAG) {
1746         free(p_header);
1747         goto reconfig;
1748     }
1749
1750     if(p_header)
1751     {
1752         p_header->nFilledLen = p_block->i_buffer;
1753         p_header->nOffset = 0;
1754         p_header->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
1755         p_header->nTimeStamp = ToOmxTicks(p_block->i_dts);
1756
1757         /* In direct mode we pass the input pointer as is.
1758          * Otherwise we memcopy the data */
1759         if(p_sys->in.b_direct)
1760         {
1761             p_header->pOutputPortPrivate = p_header->pBuffer;
1762             p_header->pBuffer = p_block->p_buffer;
1763             p_header->pAppPrivate = p_block;
1764         }
1765         else
1766         {
1767             if(p_header->nFilledLen > p_header->nAllocLen)
1768             {
1769                 msg_Dbg(p_dec, "buffer too small (%i,%i)",
1770                         (int)p_header->nFilledLen, (int)p_header->nAllocLen);
1771                 p_header->nFilledLen = p_header->nAllocLen;
1772             }
1773             memcpy(p_header->pBuffer, p_block->p_buffer, p_header->nFilledLen );
1774             block_Release(p_block);
1775         }
1776
1777         OMX_DBG( "EmptyThisBuffer %p, %p, %i", p_header, p_header->pBuffer,
1778                  (int)p_header->nFilledLen );
1779         OMX_EmptyThisBuffer(p_sys->omx_handle, p_header);
1780         p_sys->in.b_flushed = false;
1781         *pp_block = NULL; /* Avoid being fed the same packet again */
1782     }
1783
1784 reconfig:
1785     /* Handle the PortSettingsChanged events */
1786     for(i = 0; i < p_sys->ports; i++)
1787     {
1788         OmxPort *p_port = &p_sys->p_ports[i];
1789         if(!p_port->b_reconfigure) continue;
1790         p_port->b_reconfigure = 0;
1791         omx_error = PortReconfigure(p_dec, p_port);
1792         CHECK_ERROR(omx_error, "PortReconfigure failed");
1793     }
1794
1795     return p_buffer;
1796 error:
1797     p_sys->b_error = true;
1798     return NULL;
1799 }
1800
1801 /*****************************************************************************
1802  * EncodeVideo: Called to encode one frame
1803  *****************************************************************************/
1804 static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pic )
1805 {
1806     decoder_t *p_dec = ( decoder_t *)p_enc;
1807     decoder_sys_t *p_sys = p_dec->p_sys;
1808     OMX_ERRORTYPE omx_error;
1809     unsigned int i;
1810
1811     OMX_BUFFERHEADERTYPE *p_header;
1812     block_t *p_block = 0;
1813
1814     if( !p_pic ) return NULL;
1815
1816     /* Check for errors from codec */
1817     if(p_sys->b_error)
1818     {
1819         msg_Dbg(p_dec, "error during encoding");
1820         return NULL;
1821     }
1822
1823     /* Send the input buffer to the component */
1824     OMX_FIFO_GET(&p_sys->in.fifo, p_header);
1825     if(p_header)
1826     {
1827         /* In direct mode we pass the input pointer as is.
1828          * Otherwise we memcopy the data */
1829         if(p_sys->in.b_direct)
1830         {
1831             p_header->pOutputPortPrivate = p_header->pBuffer;
1832             p_header->pBuffer = p_pic->p[0].p_pixels;
1833         }
1834         else
1835         {
1836             CopyVlcPicture(p_dec, p_header, p_pic);
1837         }
1838
1839         p_header->nFilledLen = p_sys->in.i_frame_size;
1840         p_header->nOffset = 0;
1841         p_header->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
1842         p_header->nTimeStamp = ToOmxTicks(p_pic->date);
1843         OMX_DBG( "EmptyThisBuffer %p, %p, %i", p_header, p_header->pBuffer,
1844                  (int)p_header->nFilledLen );
1845         OMX_EmptyThisBuffer(p_sys->omx_handle, p_header);
1846         p_sys->in.b_flushed = false;
1847     }
1848
1849     /* Handle the PortSettingsChanged events */
1850     for(i = 0; i < p_sys->ports; i++)
1851     {
1852         OmxPort *p_port = &p_sys->p_ports[i];
1853         if(!p_port->b_reconfigure) continue;
1854         p_port->b_reconfigure = 0;
1855         omx_error = PortReconfigure(p_dec, p_port);
1856         CHECK_ERROR(omx_error, "PortReconfigure failed");
1857     }
1858
1859     /* Wait for the decoded frame */
1860     while(!p_block)
1861     {
1862         OMX_FIFO_GET(&p_sys->out.fifo, p_header);
1863
1864         if(p_header->nFilledLen)
1865         {
1866             if(p_header->nFlags & OMX_BUFFERFLAG_CODECCONFIG)
1867             {
1868                 /* TODO: need to store codec config */
1869                 msg_Dbg(p_dec, "received codec config %i", (int)p_header->nFilledLen);
1870             }
1871
1872             p_block = p_header->pAppPrivate;
1873             if(!p_block)
1874             {
1875                 /* We're not in direct rendering mode.
1876                  * Get a new block and copy the content */
1877                 p_block = block_Alloc( p_header->nFilledLen );
1878                 memcpy(p_block->p_buffer, p_header->pBuffer, p_header->nFilledLen );
1879             }
1880
1881             p_block->i_buffer = p_header->nFilledLen;
1882             p_block->i_pts = p_block->i_dts = FromOmxTicks(p_header->nTimeStamp);
1883             p_header->nFilledLen = 0;
1884             p_header->pAppPrivate = 0;
1885         }
1886
1887         OMX_DBG( "FillThisBuffer %p, %p", p_header, p_header->pBuffer );
1888         OMX_FillThisBuffer(p_sys->omx_handle, p_header);
1889     }
1890
1891     msg_Dbg(p_dec, "done");
1892     return p_block;
1893 error:
1894     p_sys->b_error = true;
1895     return NULL;
1896 }
1897
1898 /*****************************************************************************
1899  * CloseGeneric: omxil decoder destruction
1900  *****************************************************************************/
1901 static void CloseGeneric( vlc_object_t *p_this )
1902 {
1903     decoder_t *p_dec = (decoder_t *)p_this;
1904     decoder_sys_t *p_sys = p_dec->p_sys;
1905
1906     if(p_sys->omx_handle) DeinitialiseComponent(p_dec, p_sys->omx_handle);
1907
1908     DeinitOmxCore();
1909
1910     DeinitOmxEventQueue(&p_sys->event_queue);
1911
1912     OMX_FIFO_DESTROY( &p_sys->in.fifo );
1913     OMX_FIFO_DESTROY( &p_sys->out.fifo );
1914
1915     free( p_sys );
1916 }
1917
1918 /*****************************************************************************
1919  * OmxEventHandler:
1920  *****************************************************************************/
1921 static OMX_ERRORTYPE OmxEventHandler( OMX_HANDLETYPE omx_handle,
1922     OMX_PTR app_data, OMX_EVENTTYPE event, OMX_U32 data_1,
1923     OMX_U32 data_2, OMX_PTR event_data )
1924 {
1925     decoder_t *p_dec = (decoder_t *)app_data;
1926     decoder_sys_t *p_sys = p_dec->p_sys;
1927     unsigned int i;
1928     (void)omx_handle;
1929
1930     PrintOmxEvent((vlc_object_t *) p_dec, event, data_1, data_2, event_data);
1931     switch (event)
1932     {
1933     case OMX_EventError:
1934         //p_sys->b_error = true;
1935         break;
1936
1937     case OMX_EventPortSettingsChanged:
1938         if( data_2 == 0 || data_2 == OMX_IndexParamPortDefinition ||
1939             data_2 == OMX_IndexParamAudioPcm )
1940         {
1941             OMX_BUFFERHEADERTYPE *sentinel;
1942             for(i = 0; i < p_sys->ports; i++)
1943                 if(p_sys->p_ports[i].definition.eDir == OMX_DirOutput)
1944                     p_sys->p_ports[i].b_reconfigure = true;
1945             sentinel = calloc(1, sizeof(*sentinel));
1946             if (sentinel) {
1947                 sentinel->nFlags = SENTINEL_FLAG;
1948                 OMX_FIFO_PUT(&p_sys->in.fifo, sentinel);
1949             }
1950         }
1951         else if( data_2 == OMX_IndexConfigCommonOutputCrop )
1952         {
1953             for(i = 0; i < p_sys->ports; i++)
1954                 if(p_sys->p_ports[i].definition.nPortIndex == data_1)
1955                     p_sys->p_ports[i].b_update_def = true;
1956         }
1957         else
1958         {
1959             msg_Dbg( p_dec, "Unhandled setting change %x", (unsigned int)data_2 );
1960         }
1961         break;
1962     case OMX_EventParamOrConfigChanged:
1963         UpdatePixelAspect(p_dec);
1964         break;
1965
1966     default:
1967         break;
1968     }
1969
1970     PostOmxEvent(&p_sys->event_queue, event, data_1, data_2, event_data);
1971     return OMX_ErrorNone;
1972 }
1973
1974 static OMX_ERRORTYPE OmxEmptyBufferDone( OMX_HANDLETYPE omx_handle,
1975     OMX_PTR app_data, OMX_BUFFERHEADERTYPE *omx_header )
1976 {
1977     decoder_t *p_dec = (decoder_t *)app_data;
1978     decoder_sys_t *p_sys = p_dec->p_sys;
1979     (void)omx_handle;
1980
1981     OMX_DBG( "OmxEmptyBufferDone %p, %p", omx_header, omx_header->pBuffer );
1982
1983     if(omx_header->pAppPrivate || omx_header->pOutputPortPrivate)
1984     {
1985         block_t *p_block = (block_t *)omx_header->pAppPrivate;
1986         omx_header->pBuffer = omx_header->pOutputPortPrivate;
1987         if(p_block) block_Release(p_block);
1988         omx_header->pAppPrivate = 0;
1989     }
1990     OMX_FIFO_PUT(&p_sys->in.fifo, omx_header);
1991
1992     return OMX_ErrorNone;
1993 }
1994
1995 static OMX_ERRORTYPE OmxFillBufferDone( OMX_HANDLETYPE omx_handle,
1996     OMX_PTR app_data, OMX_BUFFERHEADERTYPE *omx_header )
1997 {
1998     decoder_t *p_dec = (decoder_t *)app_data;
1999     decoder_sys_t *p_sys = p_dec->p_sys;
2000     (void)omx_handle;
2001
2002     OMX_DBG( "OmxFillBufferDone %p, %p, %i, %"PRId64, omx_header, omx_header->pBuffer,
2003              (int)omx_header->nFilledLen, FromOmxTicks(omx_header->nTimeStamp) );
2004
2005     if(omx_header->pInputPortPrivate)
2006     {
2007         omx_header->pBuffer = omx_header->pInputPortPrivate;
2008     }
2009     OMX_FIFO_PUT(&p_sys->out.fifo, omx_header);
2010
2011     return OMX_ErrorNone;
2012 }
2013
2014 #if defined(USE_IOMX)
2015
2016 /* Life cycle of buffers when using IOMX direct rendering (HwBuffer):
2017  *
2018  * <- android display
2019  * DequeueThread owned++
2020  * -> OMX_FillThisBuffer
2021  * ...
2022  * <- FillBufferDone OMX_FIFO_PUT
2023  * ...
2024  * DecodeVideoOutput OMX_FIFO_GET
2025  * -> vlc core
2026  * ...
2027  * DisplayBuffer
2028  * -> android display owned--
2029  */
2030
2031 /*****************************************************************************
2032  * HwBuffer_ChangeState
2033  *****************************************************************************/
2034 static void HwBuffer_ChangeState( decoder_t *p_dec, OmxPort *p_port,
2035                                   int i_index, int i_state )
2036 {
2037     VLC_UNUSED( p_dec );
2038     p_port->p_hwbuf->i_states[i_index] = i_state;
2039     if( i_state == BUF_STATE_OWNED )
2040         p_port->p_hwbuf->i_owned++;
2041     else
2042         p_port->p_hwbuf->i_owned--;
2043
2044     OMX_DBG( "buffer[%d]: state -> %d, owned buffers: %u",
2045              i_index, i_state, p_port->p_hwbuf->i_owned );
2046 }
2047
2048 /*****************************************************************************
2049  * HwBuffer_Init
2050  *****************************************************************************/
2051 static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port )
2052 {
2053     VLC_UNUSED( p_dec );
2054     void *surf;
2055     JNIEnv *p_env;
2056     OMX_ERRORTYPE omx_error;
2057
2058     if( !p_port->b_direct || p_port->definition.eDir != OMX_DirOutput ||
2059         p_port->p_fmt->i_cat != VIDEO_ES )
2060         return;
2061
2062     msg_Dbg( p_dec, "HwBuffer_Init");
2063
2064     if( !(pf_enable_graphic_buffers && pf_get_graphic_buffer_usage &&
2065           pf_get_hal_format &&
2066           ((OMX_COMPONENTTYPE*)p_port->omx_handle)->UseBuffer) )
2067     {
2068         msg_Warn( p_dec, "direct output port enabled but can't find "
2069                           "extra symbols, switch back to non direct" );
2070         goto error;
2071     }
2072
2073     p_port->p_hwbuf = calloc(1, sizeof(HwBuffer));
2074     if( !p_port->p_hwbuf )
2075     {
2076         goto error;
2077     }
2078     vlc_cond_init (&p_port->p_hwbuf->wait);
2079     p_port->p_hwbuf->p_library = LoadNativeWindowAPI( &p_port->p_hwbuf->native_window );
2080     if( !p_port->p_hwbuf->p_library )
2081     {
2082         msg_Warn( p_dec, "LoadNativeWindowAPI failed" );
2083         goto error;
2084     }
2085     if( LoadNativeWindowPrivAPI( &p_port->p_hwbuf->anwpriv ) != 0 )
2086     {
2087         msg_Warn( p_dec, "LoadNativeWindowPrivAPI failed" );
2088         goto error;
2089     }
2090
2091     surf = jni_LockAndGetAndroidJavaSurface();
2092     if( !surf ) {
2093         jni_UnlockAndroidSurface();
2094         msg_Warn( p_dec, "jni_LockAndGetAndroidJavaSurface failed" );
2095         goto error;
2096     }
2097
2098     jni_attach_thread( &p_env, THREAD_NAME );
2099     p_port->p_hwbuf->window = p_port->p_hwbuf->native_window.winFromSurface( p_env, surf );
2100     jni_detach_thread();
2101
2102     jni_UnlockAndroidSurface();
2103     if( !p_port->p_hwbuf->window ) {
2104         msg_Warn( p_dec, "winFromSurface failed" );
2105         goto error;
2106     }
2107     p_port->p_hwbuf->anwpriv.connect( p_port->p_hwbuf->window );
2108
2109     omx_error = pf_enable_graphic_buffers( p_port->omx_handle,
2110                                            p_port->i_port_index, OMX_TRUE );
2111     CHECK_ERROR( omx_error, "can't enable graphic buffers" );
2112
2113     /* PortDefinition may change after pf_enable_graphic_buffers call */
2114     omx_error = OMX_GetParameter( p_port->omx_handle,
2115                                   OMX_IndexParamPortDefinition,
2116                                   &p_port->definition );
2117     CHECK_ERROR( omx_error, "OMX_GetParameter failed (GraphicBuffers) (%x : %s)",
2118                  omx_error, ErrorToString(omx_error) );
2119
2120
2121     msg_Dbg( p_dec, "direct output port enabled" );
2122     return;
2123 error:
2124     /* if HwBuffer_Init fails, we can fall back to non direct buffers */
2125     HwBuffer_Destroy( p_dec, p_port );
2126 }
2127
2128 /*****************************************************************************
2129  * HwBuffer_Destroy
2130  *****************************************************************************/
2131 static void HwBuffer_Destroy( decoder_t *p_dec, OmxPort *p_port )
2132 {
2133     if( p_port->p_hwbuf )
2134     {
2135         if( p_port->p_hwbuf->p_library )
2136         {
2137             if( p_port->p_hwbuf->window )
2138             {
2139                 HwBuffer_Stop( p_dec, p_port );
2140                 HwBuffer_FreeBuffers( p_dec, p_port );
2141                 HwBuffer_Join( p_dec, p_port );
2142                 p_port->p_hwbuf->anwpriv.disconnect( p_port->p_hwbuf->window );
2143                 pf_enable_graphic_buffers( p_port->omx_handle,
2144                                            p_port->i_port_index, OMX_FALSE );
2145                 p_port->p_hwbuf->native_window.winRelease( p_port->p_hwbuf->window );
2146             }
2147             dlclose( p_port->p_hwbuf->p_library );
2148         }
2149
2150         vlc_cond_destroy( &p_port->p_hwbuf->wait );
2151         free( p_port->p_hwbuf );
2152         p_port->p_hwbuf = NULL;
2153     }
2154     p_port->b_direct = false;
2155 }
2156
2157 /*****************************************************************************
2158  * HwBuffer_AllocateBuffers
2159  *****************************************************************************/
2160 static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
2161 {
2162     decoder_sys_t *p_sys = p_dec->p_sys;
2163     OMX_PARAM_PORTDEFINITIONTYPE *def = &p_port->definition;
2164     unsigned int min_undequeued = 0;
2165     unsigned int i = 0;
2166     int colorFormat = def->format.video.eColorFormat;
2167     OMX_ERRORTYPE omx_error;
2168     OMX_U32 i_hw_usage;
2169
2170     if( !p_port->p_hwbuf )
2171         return 0;
2172
2173     omx_error = pf_get_hal_format( p_sys->psz_component, &colorFormat );
2174     if( omx_error != OMX_ErrorNone )
2175     {
2176         msg_Warn( p_dec, "pf_get_hal_format failed (Not fatal)" );
2177     }
2178
2179     omx_error = pf_get_graphic_buffer_usage( p_port->omx_handle,
2180                                              p_port->i_port_index,
2181                                              &i_hw_usage );
2182     if( omx_error != OMX_ErrorNone )
2183     {
2184         msg_Warn( p_dec, "pf_get_graphic_buffer_usage failed (Not fatal)" );
2185         i_hw_usage = 0;
2186     }
2187
2188     if( p_port->p_fmt->video.orientation != ORIENT_NORMAL )
2189     {
2190         int i_angle;
2191
2192         switch( p_port->p_fmt->video.orientation )
2193         {
2194             case ORIENT_ROTATED_90:
2195                 i_angle = 90;
2196                 break;
2197             case ORIENT_ROTATED_180:
2198                 i_angle = 180;
2199                 break;
2200             case ORIENT_ROTATED_270:
2201                 i_angle = 270;
2202                 break;
2203             default:
2204                 i_angle = 0;
2205         }
2206         p_port->p_hwbuf->anwpriv.setOrientation( p_port->p_hwbuf->window,
2207                                                  i_angle );
2208         video_format_ApplyRotation( &p_port->p_hwbuf->fmt_out,
2209                                     &p_port->p_fmt->video );
2210     } else
2211         p_port->p_hwbuf->fmt_out = p_port->p_fmt->video;
2212
2213     if( p_port->p_hwbuf->anwpriv.setup( p_port->p_hwbuf->window,
2214                                         def->format.video.nFrameWidth,
2215                                         def->format.video.nFrameHeight,
2216                                         colorFormat,
2217                                         (int) i_hw_usage ) != 0 )
2218     {
2219         msg_Err( p_dec, "can't setup OMXHWBuffer" );
2220         goto error;
2221     }
2222
2223     if( p_port->p_hwbuf->anwpriv.getMinUndequeued( p_port->p_hwbuf->window,
2224                                                    &min_undequeued ) != 0 )
2225     {
2226         msg_Err( p_dec, "can't get min_undequeued" );
2227         goto error;
2228     }
2229
2230     if( def->nBufferCountActual < def->nBufferCountMin + min_undequeued )
2231     {
2232         unsigned int new_frames_num = def->nBufferCountMin + min_undequeued;
2233
2234         OMX_DBG( "AllocateBuffers: video out wants more frames: %lu vs %u",
2235                  p_port->definition.nBufferCountActual, new_frames_num );
2236
2237         p_port->definition.nBufferCountActual = new_frames_num;
2238         omx_error = OMX_SetParameter( p_dec->p_sys->omx_handle,
2239                                       OMX_IndexParamPortDefinition,
2240                                       &p_port->definition );
2241         CHECK_ERROR( omx_error, "OMX_SetParameter failed (%x : %s)",
2242                      omx_error, ErrorToString(omx_error) );
2243     }
2244
2245     if( p_port->p_hwbuf->anwpriv.setBufferCount( p_port->p_hwbuf->window,
2246                                                  def->nBufferCountActual ) != 0 )
2247     {
2248         msg_Err( p_dec, "can't set buffer_count" );
2249         goto error;
2250     }
2251
2252     jni_SetAndroidSurfaceSize( p_port->p_hwbuf->fmt_out.i_width,
2253                                p_port->p_hwbuf->fmt_out.i_height,
2254                                p_port->p_hwbuf->fmt_out.i_visible_width,
2255                                p_port->p_hwbuf->fmt_out.i_visible_height,
2256                                p_port->p_hwbuf->fmt_out.i_sar_num,
2257                                p_port->p_hwbuf->fmt_out.i_sar_den );
2258
2259     p_port->p_hwbuf->i_buffers = p_port->definition.nBufferCountActual;
2260     p_port->p_hwbuf->i_max_owned = p_port->p_hwbuf->i_buffers - min_undequeued;
2261
2262     p_port->p_hwbuf->pp_handles = calloc( p_port->p_hwbuf->i_buffers,
2263                                           sizeof(void *) );
2264     if( !p_port->p_hwbuf->pp_handles )
2265         goto error;
2266
2267     p_port->p_hwbuf->i_states = calloc( p_port->p_hwbuf->i_buffers, sizeof(int) );
2268     if( !p_port->p_hwbuf->i_states )
2269         goto error;
2270
2271     p_port->p_hwbuf->inflight_picture = calloc( p_port->p_hwbuf->i_buffers,
2272                                                 sizeof(picture_t*) );
2273     if( !p_port->p_hwbuf->inflight_picture )
2274         goto error;
2275
2276     for(i = 0; i < p_port->p_hwbuf->i_buffers; i++)
2277     {
2278         void *p_handle = NULL;
2279
2280         if( p_port->p_hwbuf->anwpriv.dequeue( p_port->p_hwbuf->window,
2281                                               &p_handle ) != 0 )
2282         {
2283             msg_Err( p_dec, "OMXHWBuffer_dequeue Fail" );
2284             goto error;
2285         }
2286         p_port->p_hwbuf->pp_handles[i] = p_handle;
2287     }
2288     for(i = 0; i < p_port->p_hwbuf->i_max_owned; i++)
2289         HwBuffer_ChangeState( p_dec, p_port, i, BUF_STATE_OWNED );
2290     for(; i < p_port->p_hwbuf->i_buffers; i++)
2291     {
2292         OMX_DBG( "canceling buffer(%d)", i );
2293         p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window,
2294                                          p_port->p_hwbuf->pp_handles[i] );
2295     }
2296
2297     return 0;
2298
2299 error:
2300
2301     msg_Err( p_dec, "HwBuffer_AllocateBuffers(%d) failed", def->eDir );
2302     return -1;
2303 }
2304
2305 /*****************************************************************************
2306  * HwBuffer_FreeBuffers
2307  *****************************************************************************/
2308 static int HwBuffer_FreeBuffers( decoder_t *p_dec, OmxPort *p_port )
2309 {
2310     msg_Dbg( p_dec, "HwBuffer_FreeBuffers");
2311
2312     HWBUFFER_LOCK();
2313
2314     p_port->p_hwbuf->b_run = false;
2315
2316     if( p_port->p_hwbuf->pp_handles )
2317     {
2318         for(unsigned int i = 0; i < p_port->p_hwbuf->i_buffers; i++)
2319         {
2320             void *p_handle = p_port->p_hwbuf->pp_handles[i];
2321
2322             if( p_handle && p_port->p_hwbuf->i_states[i] == BUF_STATE_OWNED )
2323             {
2324                 p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window, p_handle );
2325                 HwBuffer_ChangeState( p_dec, p_port, i, BUF_STATE_NOT_OWNED );
2326             }
2327         }
2328     }
2329     HWBUFFER_BROADCAST( p_port );
2330
2331     HWBUFFER_UNLOCK();
2332
2333     p_port->p_hwbuf->i_buffers = 0;
2334
2335     free( p_port->p_hwbuf->pp_handles );
2336     p_port->p_hwbuf->pp_handles = NULL;
2337
2338     free( p_port->p_hwbuf->i_states );
2339     p_port->p_hwbuf->i_states = NULL;
2340
2341     free( p_port->p_hwbuf->inflight_picture );
2342     p_port->p_hwbuf->inflight_picture = NULL;
2343
2344     return 0;
2345 }
2346
2347 /*****************************************************************************
2348  * HwBuffer_Start
2349  *****************************************************************************/
2350 static int HwBuffer_Start( decoder_t *p_dec, OmxPort *p_port )
2351 {
2352     OMX_BUFFERHEADERTYPE *p_header;
2353
2354     msg_Dbg( p_dec, "HwBuffer_Start" );
2355     HWBUFFER_LOCK();
2356
2357     /* fill all owned buffers dequeued by HwBuffer_AllocatesBuffers */
2358     for(unsigned int i = 0; i < p_port->p_hwbuf->i_buffers; i++)
2359     {
2360         p_header = p_port->pp_buffers[i];
2361
2362         if( p_header && p_port->p_hwbuf->i_states[i] == BUF_STATE_OWNED )
2363         {
2364             if( p_port->p_hwbuf->anwpriv.lock( p_port->p_hwbuf->window,
2365                                                p_header->pBuffer ) != 0 )
2366             {
2367                 msg_Err( p_dec, "lock failed" );
2368                 HWBUFFER_UNLOCK();
2369                 return -1;
2370             }
2371             OMX_DBG( "FillThisBuffer %p, %p", p_header, p_header->pBuffer );
2372             OMX_FillThisBuffer( p_port->omx_handle, p_header );
2373         }
2374     }
2375
2376     p_port->p_hwbuf->b_run = true;
2377     if( vlc_clone( &p_port->p_hwbuf->dequeue_thread,
2378                    DequeueThread, p_dec, VLC_THREAD_PRIORITY_LOW ) )
2379     {
2380         p_port->p_hwbuf->b_run = false;
2381         HWBUFFER_UNLOCK();
2382         return -1;
2383     }
2384
2385     HWBUFFER_UNLOCK();
2386
2387     return 0;
2388 }
2389
2390 /*****************************************************************************
2391  * HwBuffer_Stop: stop DequeueThread and invalidate all pictures that are sent
2392  * to vlc core. The thread can be stuck in dequeue, so don't
2393  * join it now since it can be unblocked later by HwBuffer_FreeBuffers.
2394  *****************************************************************************/
2395 static int HwBuffer_Stop( decoder_t *p_dec, OmxPort *p_port )
2396 {
2397     VLC_UNUSED( p_dec );
2398
2399     msg_Dbg( p_dec, "HwBuffer_Stop" );
2400     HWBUFFER_LOCK();
2401
2402     p_port->p_hwbuf->b_run = false;
2403
2404     /* invalidate and release all inflight pictures */
2405     if( p_port->p_hwbuf->inflight_picture ) {
2406         for( unsigned int i = 0; i < p_port->i_buffers; ++i ) {
2407             picture_t *p_pic = p_port->p_hwbuf->inflight_picture[i];
2408             if( p_pic ) {
2409                 picture_sys_t *p_picsys = p_pic->p_sys;
2410                 if( p_picsys ) {
2411                     void *p_handle = p_port->pp_buffers[p_picsys->i_index]->pBuffer;
2412                     if( p_handle )
2413                     {
2414                         p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window, p_handle );
2415                         HwBuffer_ChangeState( p_dec, p_port, p_picsys->i_index,
2416                                               BUF_STATE_NOT_OWNED );
2417                     }
2418                     p_picsys->b_valid = false;
2419                 }
2420                 p_port->p_hwbuf->inflight_picture[i] = NULL;
2421             }
2422         }
2423     }
2424
2425     HWBUFFER_BROADCAST( p_port );
2426
2427     HWBUFFER_UNLOCK();
2428
2429     return 0;
2430 }
2431
2432 /*****************************************************************************
2433  * HwBuffer_Join: join DequeueThread previously stopped by HwBuffer_Stop.
2434  *****************************************************************************/
2435 static int HwBuffer_Join( decoder_t *p_dec, OmxPort *p_port )
2436 {
2437     VLC_UNUSED( p_dec );
2438
2439     if( p_port->p_hwbuf->dequeue_thread )
2440     {
2441         vlc_join( p_port->p_hwbuf->dequeue_thread, NULL );
2442         p_port->p_hwbuf->dequeue_thread = NULL;
2443     }
2444     return 0;
2445 }
2446
2447 /*****************************************************************************
2448  * HwBuffer_GetPic
2449  *****************************************************************************/
2450 static int HwBuffer_GetPic( decoder_t *p_dec, OmxPort *p_port,
2451                             picture_t **pp_pic)
2452 {
2453     int i_index = -1;
2454     picture_t *p_pic;
2455     picture_sys_t *p_picsys;
2456     OMX_BUFFERHEADERTYPE *p_header;
2457
2458     OMX_FIFO_PEEK(&p_port->fifo, p_header);
2459
2460     if( !p_header )
2461         return 0;
2462
2463     for(unsigned int i = 0; i < p_port->i_buffers; i++)
2464     {
2465         if( p_port->pp_buffers[i] == p_header )
2466         {
2467             i_index = i;
2468             break;
2469         }
2470     }
2471     if( i_index == -1 )
2472     {
2473         msg_Err( p_dec, "output buffer not found" );
2474         return -1;
2475     }
2476
2477     p_pic = decoder_NewPicture( p_dec );
2478     if(!p_pic)
2479     {
2480         msg_Err( p_dec, "decoder_NewPicture failed" );
2481         return -1;
2482     }
2483     p_pic->date = FromOmxTicks( p_header->nTimeStamp );
2484
2485     p_picsys = p_pic->p_sys;
2486     p_picsys->pf_display_callback = DisplayCallback;
2487     p_picsys->pf_unlock_callback = UnlockCallback;
2488     p_picsys->p_dec = p_dec;
2489     p_picsys->i_index = i_index;
2490     p_picsys->b_valid = true;
2491
2492     HWBUFFER_LOCK();
2493     p_port->p_hwbuf->inflight_picture[i_index] = p_pic;
2494     HWBUFFER_UNLOCK();
2495
2496     *pp_pic = p_pic;
2497     OMX_FIFO_GET( &p_port->fifo, p_header );
2498     return 0;
2499 }
2500
2501 /*****************************************************************************
2502  * HwBuffer_SetCrop
2503  *****************************************************************************/
2504 static void HwBuffer_SetCrop( decoder_t *p_dec, OmxPort *p_port,
2505                               OMX_CONFIG_RECTTYPE *p_rect )
2506 {
2507     VLC_UNUSED( p_dec );
2508
2509     p_port->p_hwbuf->anwpriv.setCrop( p_port->p_hwbuf->window,
2510                                       p_rect->nLeft, p_rect->nTop,
2511                                       p_rect->nWidth, p_rect->nHeight );
2512 }
2513
2514 /*****************************************************************************
2515  * DequeueThread
2516  *****************************************************************************/
2517 static void *DequeueThread( void *data )
2518 {
2519     decoder_t *p_dec = data;
2520     decoder_sys_t *p_sys = p_dec->p_sys;;
2521     OmxPort *p_port = &p_sys->out;
2522     unsigned int i;
2523     int i_index = -1;
2524     int err;
2525     void *p_handle = NULL;
2526     OMX_BUFFERHEADERTYPE *p_header;
2527
2528     msg_Dbg( p_dec, "DequeueThread running");
2529     HWBUFFER_LOCK();
2530     while( p_port->p_hwbuf->b_run )
2531     {
2532         while( p_port->p_hwbuf->b_run &&
2533                p_port->p_hwbuf->i_owned >= p_port->p_hwbuf->i_max_owned )
2534             HWBUFFER_WAIT( p_port );
2535
2536         if( !p_port->p_hwbuf->b_run ) continue;
2537
2538         HWBUFFER_UNLOCK();
2539
2540
2541         /* The thread can be stuck here. It shouldn't happen since we make sure
2542          * we call the dequeue function if there is at least one buffer
2543          * available. */
2544         err = p_port->p_hwbuf->anwpriv.dequeue( p_port->p_hwbuf->window, &p_handle );
2545         if( err == 0 )
2546             err = p_port->p_hwbuf->anwpriv.lock( p_port->p_hwbuf->window, p_handle );
2547
2548         HWBUFFER_LOCK();
2549
2550         if( err != 0 ) {
2551             if( err != -EBUSY )
2552                 p_port->p_hwbuf->b_run = false;
2553             continue;
2554         }
2555
2556         if( !p_port->p_hwbuf->b_run )
2557         {
2558             p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window, p_handle );
2559             continue;
2560         }
2561
2562         for(i = 0; i < p_port->i_buffers; i++)
2563         {
2564             if( p_port->pp_buffers[i]->pBuffer == p_handle )
2565             {
2566                 i_index = i;
2567                 p_header = p_port->pp_buffers[i_index];
2568                 break;
2569             }
2570         }
2571         if( i_index == -1 )
2572         {
2573             msg_Err( p_dec, "p_port->p_hwbuf->anwpriv.dequeue returned unknown handle" );
2574             continue;
2575         }
2576
2577         HwBuffer_ChangeState( p_dec, p_port, i_index, BUF_STATE_OWNED );
2578
2579         OMX_DBG( "FillThisBuffer %p, %p", p_header, p_header->pBuffer );
2580         OMX_FillThisBuffer( p_sys->omx_handle, p_header );
2581
2582         HWBUFFER_BROADCAST( p_port );
2583     }
2584     HWBUFFER_UNLOCK();
2585
2586     msg_Dbg( p_dec, "DequeueThread stopped");
2587     return NULL;
2588 }
2589
2590 /*****************************************************************************
2591  * vout callbacks
2592  *****************************************************************************/
2593 static void DisplayBuffer( picture_sys_t* p_picsys, bool b_render )
2594 {
2595     decoder_t *p_dec = p_picsys->p_dec;
2596     decoder_sys_t *p_sys = p_dec->p_sys;
2597     OmxPort *p_port = &p_sys->out;
2598     void *p_handle;
2599
2600     if( !p_picsys->b_valid ) return;
2601
2602     HWBUFFER_LOCK();
2603
2604     /* Picture might have been invalidated while waiting on the mutex. */
2605     if (!p_picsys->b_valid) {
2606         HWBUFFER_UNLOCK();
2607         return;
2608     }
2609
2610     p_handle = p_port->pp_buffers[p_picsys->i_index]->pBuffer;
2611
2612     OMX_DBG( "DisplayBuffer: %s %p",
2613              b_render ? "render" : "cancel", p_handle );
2614
2615     if( !p_handle )
2616     {
2617         msg_Err( p_dec, "DisplayBuffer: buffer handle invalid" );
2618         goto end;
2619     }
2620
2621     if( b_render )
2622         p_port->p_hwbuf->anwpriv.queue( p_port->p_hwbuf->window, p_handle );
2623     else
2624         p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window, p_handle );
2625
2626     HwBuffer_ChangeState( p_dec, p_port, p_picsys->i_index, BUF_STATE_NOT_OWNED );
2627     HWBUFFER_BROADCAST( p_port );
2628
2629     p_port->p_hwbuf->inflight_picture[p_picsys->i_index] = NULL;
2630
2631 end:
2632     p_picsys->b_valid = false;
2633     p_picsys->i_index = -1;
2634
2635     HWBUFFER_UNLOCK();
2636 }
2637
2638 static void UnlockCallback( picture_sys_t* p_picsys )
2639 {
2640     DisplayBuffer( p_picsys, false );
2641 }
2642
2643 static void DisplayCallback( picture_sys_t* p_picsys )
2644 {
2645     DisplayBuffer( p_picsys, true );
2646 }
2647
2648 #endif // USE_IOMX