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