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