]> git.sesse.net Git - vlc/commitdiff
iomx-dr: split IOMXHWBuffer_Setup function
authorThomas Guillem <guillem@archos.com>
Fri, 25 Jul 2014 14:58:54 +0000 (16:58 +0200)
committerMartin Storsjö <martin@martin.st>
Sat, 26 Jul 2014 11:00:09 +0000 (14:00 +0300)
In HwBuffer, split Setup into Setup, GetMinUndequeued and SetBufferCount since
we want to control the buffer count logic from omxil.c.

Some OMX components (like OMX.TI.*.Decoder) may have nBufferCountActual that is
greater than nBufferCountMin + min_undequeued. In that case we decreased the
number of buffer wanted by the component and had an undefined behavior.

In order to fix it, we need to increase nBufferCountActual value from the
component only when it's smaller than nBufferCountMin + min_undequeued.

Signed-off-by: Martin Storsjö <martin@martin.st>
modules/codec/omxil/iomx_hwbuffer.c
modules/codec/omxil/omxil.c
modules/codec/omxil/omxil_core.c
modules/codec/omxil/omxil_core.h

index c8619d4914dfa47059e7ca2b6a2828ad97ad45f0..4eb75482cdaffa927319c866d8ea1a842a1d9401 100644 (file)
@@ -100,8 +100,7 @@ int IOMXHWBuffer_Disconnect( void *window )
 }
 
 
-int IOMXHWBuffer_Setup( void *window, int w, int h, int hal_format, int hw_usage,
-                        unsigned int *num_frames, unsigned int *min_undequeued )
+int IOMXHWBuffer_Setup( void *window, int w, int h, int hal_format, int hw_usage )
 {
     ANativeWindow *anw = (ANativeWindow *)window;
     int usage = 0;
@@ -134,19 +133,38 @@ int IOMXHWBuffer_Setup( void *window, int w, int h, int hal_format, int hw_usage
     CHECK_ERR();
 #endif
 
+    return 0;
+}
+
+int IOMXHWBuffer_GetMinUndequeued( void *window, unsigned int *min_undequeued )
+{
+    ANativeWindow *anw = (ANativeWindow *)window;
+    status_t err;
+
+    CHECK_ANW();
 #if ANDROID_API >= 11
-    if( *min_undequeued == 0 )
-    {
-        anw->query( anw, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, min_undequeued );
-        CHECK_ERR();
-    }
+    err = anw->query( anw, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, min_undequeued );
+    CHECK_ERR();
 #endif
     /* set a minimum value of min_undequeued in case query fails */
     if( *min_undequeued == 0 )
         *min_undequeued = 2;
-    *num_frames += *min_undequeued;
 
-    err = native_window_set_buffer_count( anw, *num_frames );
+    LOGD( "IOMXHWBuffer_GetMinUndequeued: %p %u", anw, *min_undequeued );
+
+    return 0;
+}
+
+int IOMXHWBuffer_SetBufferCount(void *window, unsigned int count )
+{
+    ANativeWindow *anw = (ANativeWindow *)window;
+    status_t err;
+
+    CHECK_ANW();
+
+    LOGD( "IOMXHWBuffer_SetBufferCount: %p %u", anw, count );
+
+    err = native_window_set_buffer_count( anw, count );
     CHECK_ERR();
 
     return 0;
index ce8361392383eef9a78f3883cffbdca952aa3bce..daabe62b9723351123c68a4b10d69aa6cbc56484 100644 (file)
@@ -2017,7 +2017,8 @@ static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port )
 
     if( !(pf_enable_graphic_buffers && pf_get_graphic_buffer_usage &&
           pf_omx_hwbuffer_connect && pf_omx_hwbuffer_disconnect &&
-          pf_omx_hwbuffer_setup && pf_omx_hwbuffer_setcrop &&
+          pf_omx_hwbuffer_setup && pf_omx_hwbuffer_get_min_undequeued &&
+          pf_omx_hwbuffer_set_buffer_count && pf_omx_hwbuffer_setcrop &&
           pf_omx_hwbuffer_dequeue && pf_omx_hwbuffer_lock &&
           pf_omx_hwbuffer_queue && pf_omx_hwbuffer_cancel &&
           ((OMX_COMPONENTTYPE*)p_port->omx_handle)->UseBuffer) )
@@ -2114,7 +2115,6 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
     decoder_sys_t *p_sys = p_dec->p_sys;
     OMX_PARAM_PORTDEFINITIONTYPE *def = &p_port->definition;
     unsigned int min_undequeued = 0;
-    unsigned int num_frames = def->nBufferCountMin;
     unsigned int i = 0;
     int colorFormat = def->format.video.eColorFormat;
     OMX_ERRORTYPE omx_error;
@@ -2150,19 +2150,27 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
                                def->format.video.nFrameWidth,
                                def->format.video.nFrameHeight,
                                colorFormat,
-                               (int) i_hw_usage,
-                               &num_frames, &min_undequeued) != 0 )
+                               (int) i_hw_usage ) != 0 )
     {
         msg_Err( p_dec, "can't setup OMXHWBuffer" );
         goto error;
     }
 
-    if( num_frames != p_port->definition.nBufferCountActual )
+    if( pf_omx_hwbuffer_get_min_undequeued( p_port->p_hwbuf->window,
+                                            &min_undequeued ) != 0 )
     {
+        msg_Err( p_dec, "can't get min_undequeued" );
+        goto error;
+    }
+
+    if( def->nBufferCountActual < def->nBufferCountMin + min_undequeued )
+    {
+        unsigned int new_frames_num = def->nBufferCountMin + min_undequeued;
+
         OMX_DBG( "AllocateBuffers: video out wants more frames: %lu vs %u",
-                 p_port->definition.nBufferCountActual, num_frames);
+                 p_port->definition.nBufferCountActual, new_frames_num );
 
-        p_port->definition.nBufferCountActual = num_frames;
+        p_port->definition.nBufferCountActual = new_frames_num;
         omx_error = OMX_SetParameter( p_dec->p_sys->omx_handle,
                                       OMX_IndexParamPortDefinition,
                                       &p_port->definition );
@@ -2170,6 +2178,13 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
                      omx_error, ErrorToString(omx_error) );
     }
 
+    if( pf_omx_hwbuffer_set_buffer_count( p_port->p_hwbuf->window,
+                                          def->nBufferCountActual ) != 0 )
+    {
+        msg_Err( p_dec, "can't set buffer_count" );
+        goto error;
+    }
+
     jni_SetAndroidSurfaceSize( def->format.video.nFrameWidth,
                                def->format.video.nFrameHeight,
                                def->format.video.nFrameWidth,
index 23166b39a19644d438328f6d3548d5b7c7f224cf..aed525162811c20cc50fa4888fc0a68b0a4bdba6 100644 (file)
@@ -92,8 +92,9 @@ OMX_ERRORTYPE (*pf_get_graphic_buffer_usage)(OMX_HANDLETYPE, OMX_U32, OMX_U32*);
 
 int (*pf_omx_hwbuffer_connect) (void *);
 int (*pf_omx_hwbuffer_disconnect) (void *);
-int (*pf_omx_hwbuffer_setup) (void *, int, int, int, int, unsigned int *,
-                              unsigned int *);
+int (*pf_omx_hwbuffer_setup) (void *, int, int, int, int );
+int (*pf_omx_hwbuffer_get_min_undequeued) (void *, unsigned int *);
+int (*pf_omx_hwbuffer_set_buffer_count) (void *, unsigned int );
 int (*pf_omx_hwbuffer_setcrop) (void *, int, int, int, int);
 int (*pf_omx_hwbuffer_dequeue) (void *, void **);
 int (*pf_omx_hwbuffer_lock) (void *, void *);
@@ -179,6 +180,8 @@ int InitOmxCore(vlc_object_t *p_this)
     pf_omx_hwbuffer_connect = dlsym( dll_handle, "OMXHWBuffer_Connect" );
     pf_omx_hwbuffer_disconnect = dlsym( dll_handle, "OMXHWBuffer_Disconnect" );
     pf_omx_hwbuffer_setup = dlsym( dll_handle, "OMXHWBuffer_Setup" );
+    pf_omx_hwbuffer_get_min_undequeued = dlsym( dll_handle, "OMXHWBuffer_GetMinUndequeued" );
+    pf_omx_hwbuffer_set_buffer_count = dlsym( dll_handle, "OMXHWBuffer_SetBufferCount" );
     pf_omx_hwbuffer_setcrop = dlsym( dll_handle, "OMXHWBuffer_Setcrop" );
     pf_omx_hwbuffer_dequeue = dlsym( dll_handle, "OMXHWBuffer_Dequeue" );
     pf_omx_hwbuffer_lock = dlsym( dll_handle, "OMXHWBuffer_Lock" );
index dbf6629c19a28841455e3007a3d7af421c59febd..955e9659024176cd34630db0fb7b81bf61f31261 100644 (file)
@@ -40,8 +40,9 @@ OMX_ERRORTYPE (*pf_get_graphic_buffer_usage)(OMX_HANDLETYPE, OMX_U32, OMX_U32*);
 /* OMXHWBuffer functions */
 int (*pf_omx_hwbuffer_connect) (void *);
 int (*pf_omx_hwbuffer_disconnect) (void *);
-int (*pf_omx_hwbuffer_setup) (void *, int, int, int, int, unsigned int *,
-                              unsigned int *);
+int (*pf_omx_hwbuffer_setup) (void *, int, int, int, int );
+int (*pf_omx_hwbuffer_get_min_undequeued) (void *, unsigned int *);
+int (*pf_omx_hwbuffer_set_buffer_count) (void *, unsigned int );
 int (*pf_omx_hwbuffer_setcrop) (void *, int, int, int, int);
 int (*pf_omx_hwbuffer_dequeue) (void *, void **);
 int (*pf_omx_hwbuffer_lock) (void *, void *);