]> git.sesse.net Git - vlc/blobdiff - modules/codec/omxil/omxil.c
nativewindowpriv: split setup into setUsage and setBuffersGeometry
[vlc] / modules / codec / omxil / omxil.c
index 544d9ba5ab67c387cc5da553af07b40075caaa99..9bdedc5b0e79b24eeae4fe5196e6e3673eb06a31 100644 (file)
@@ -36,6 +36,7 @@
 #include <vlc_block_helper.h>
 #include <vlc_cpu.h>
 #include "../h264_nal.h"
+#include "../hevc_nal.h"
 
 #include "omxil.h"
 #include "omxil_core.h"
@@ -45,6 +46,7 @@
 #include <dlfcn.h>
 #include <jni.h>
 #include "android_opaque.h"
+#include "../../video_output/android/android_window.h"
 #endif
 
 #ifndef NDEBUG
 
 #if defined(USE_IOMX)
 /* JNI functions to get/set an Android Surface object. */
-extern JavaVM *myVm;
+#define THREAD_NAME "omxil"
+extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
+extern void jni_detach_thread();
 extern jobject jni_LockAndGetAndroidJavaSurface();
 extern void jni_UnlockAndroidSurface();
-extern void jni_SetAndroidSurfaceSize(int width, int height, int visible_width, int visible_height, int sar_num, int sar_den);
 extern bool jni_IsVideoPlayerActivityCreated();
 #endif
 
@@ -93,8 +96,7 @@ static OMX_ERRORTYPE OmxFillBufferDone( OMX_HANDLETYPE, OMX_PTR,
 
 #if defined(USE_IOMX)
 static void *DequeueThread( void *data );
-static void DisplayCallback( picture_sys_t* p_picsys );
-static void UnlockCallback( picture_sys_t* p_picsys );
+static void UnlockPicture( picture_t* p_pic, bool b_render );
 static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port );
 static void HwBuffer_Destroy( decoder_t *p_dec, OmxPort *p_port );
 static int  HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port );
@@ -477,7 +479,8 @@ static OMX_ERRORTYPE AllocateBuffers(decoder_t *p_dec, OmxPort *p_port)
                                p_port->i_port_index, 0,
                                p_port->definition.nBufferSize, (void*)1);
             OMX_DBG( "OMX_UseBuffer(%d) %p, %p", def->eDir,
-                     p_port->pp_buffers[i], p_port->pp_buffers[i]->pBuffer );
+                     p_port->pp_buffers[i], p_port->pp_buffers[i] ?
+                     p_port->pp_buffers[i]->pBuffer : NULL );
         }
         else
         {
@@ -486,7 +489,8 @@ static OMX_ERRORTYPE AllocateBuffers(decoder_t *p_dec, OmxPort *p_port)
                                     p_port->i_port_index, 0,
                                     p_port->definition.nBufferSize);
             OMX_DBG( "OMX_AllocateBuffer(%d) %p, %p", def->eDir,
-                     p_port->pp_buffers[i], p_port->pp_buffers[i]->pBuffer );
+                     p_port->pp_buffers[i], p_port->pp_buffers[i] ? 
+                     p_port->pp_buffers[i]->pBuffer : NULL );
         }
 
         if(omx_error != OMX_ErrorNone)
@@ -548,7 +552,7 @@ static OMX_ERRORTYPE FreeBuffers(decoder_t *p_dec, OmxPort *p_port)
         if( p_buffer )
         {
             if (p_buffer->pAppPrivate != NULL)
-                decoder_DeletePicture( p_dec, p_buffer->pAppPrivate );
+                picture_Release( p_buffer->pAppPrivate );
 
             omx_error = OMX_FreeBuffer( p_port->omx_handle,
                                         p_port->i_port_index, p_buffer );
@@ -1195,6 +1199,15 @@ static int OpenGeneric( vlc_object_t *p_this, bool b_encode )
                              p_header->pBuffer, p_header->nAllocLen,
                              (uint32_t*) &p_header->nFilledLen, NULL );
         }
+        else if( p_dec->fmt_in.i_codec == VLC_CODEC_HEVC && !p_sys->in.b_direct )
+        {
+            p_header->nFilledLen = 0;
+            convert_hevc_nal_units( p_dec, p_dec->fmt_in.p_extra,
+                                    p_dec->fmt_in.i_extra,
+                                    p_header->pBuffer, p_header->nAllocLen,
+                                    (uint32_t*) &p_header->nFilledLen,
+                                    &p_sys->i_nal_size_length );
+        }
         else if(p_sys->in.b_direct)
         {
             p_header->pOutputPortPrivate = p_header->pBuffer;
@@ -1621,11 +1634,11 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
             if (invalid_picture) {
                 invalid_picture->date = VLC_TS_INVALID;
                 picture_sys_t *p_picsys = invalid_picture->p_sys;
-                p_picsys->pf_display_callback = NULL;
-                p_picsys->pf_unlock_callback = NULL;
-                p_picsys->p_dec = NULL;
-                p_picsys->i_index = -1;
-                p_picsys->b_valid = false;
+                p_picsys->pf_lock_pic = NULL;
+                p_picsys->pf_unlock_pic = NULL;
+                p_picsys->priv.hw.p_dec = NULL;
+                p_picsys->priv.hw.i_index = -1;
+                p_picsys->priv.hw.b_valid = false;
             } else {
                 /* If we cannot return a picture we must free the
                    block since the decoder will proceed with the
@@ -2083,16 +2096,23 @@ static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port )
         goto error;
     }
 
-    (*myVm)->AttachCurrentThread( myVm, &p_env, NULL );
+    jni_attach_thread( &p_env, THREAD_NAME );
     p_port->p_hwbuf->window = p_port->p_hwbuf->native_window.winFromSurface( p_env, surf );
-    (*myVm)->DetachCurrentThread( myVm );
+    jni_detach_thread();
 
     jni_UnlockAndroidSurface();
     if( !p_port->p_hwbuf->window ) {
         msg_Warn( p_dec, "winFromSurface failed" );
         goto error;
     }
-    p_port->p_hwbuf->anwpriv.connect( p_port->p_hwbuf->window );
+    p_port->p_hwbuf->window_priv =
+        p_port->p_hwbuf->anwpriv.connect( p_port->p_hwbuf->window );
+    if( !p_port->p_hwbuf->window_priv ) {
+        msg_Warn( p_dec, "connect failed" );
+        p_port->p_hwbuf->native_window.winRelease( p_port->p_hwbuf->window );
+        p_port->p_hwbuf->window = NULL;
+        goto error;
+    }
 
     omx_error = pf_enable_graphic_buffers( p_port->omx_handle,
                                            p_port->i_port_index, OMX_TRUE );
@@ -2127,7 +2147,7 @@ static void HwBuffer_Destroy( decoder_t *p_dec, OmxPort *p_port )
                 HwBuffer_Stop( p_dec, p_port );
                 HwBuffer_FreeBuffers( p_dec, p_port );
                 HwBuffer_Join( p_dec, p_port );
-                p_port->p_hwbuf->anwpriv.disconnect( p_port->p_hwbuf->window );
+                p_port->p_hwbuf->anwpriv.disconnect( p_port->p_hwbuf->window_priv );
                 pf_enable_graphic_buffers( p_port->omx_handle,
                                            p_port->i_port_index, OMX_FALSE );
                 p_port->p_hwbuf->native_window.winRelease( p_port->p_hwbuf->window );
@@ -2191,24 +2211,26 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
             default:
                 i_angle = 0;
         }
-        p_port->p_hwbuf->anwpriv.setOrientation( p_port->p_hwbuf->window,
+        p_port->p_hwbuf->anwpriv.setOrientation( p_port->p_hwbuf->window_priv,
                                                  i_angle );
-        video_format_ApplyRotation( &p_port->p_hwbuf->fmt_out,
-                                    &p_port->p_fmt->video );
-    } else
-        p_port->p_hwbuf->fmt_out = p_port->p_fmt->video;
-
-    if( p_port->p_hwbuf->anwpriv.setup( p_port->p_hwbuf->window,
-                                        def->format.video.nFrameWidth,
-                                        def->format.video.nFrameHeight,
-                                        colorFormat,
-                                        (int) i_hw_usage ) != 0 )
-    {
-        msg_Err( p_dec, "can't setup OMXHWBuffer" );
+    }
+
+    if( p_port->p_hwbuf->anwpriv.setUsage( p_port->p_hwbuf->window_priv,
+                                           true, (int) i_hw_usage ) != 0 )
+    {
+        msg_Err( p_dec, "can't set usage" );
+        goto error;
+    }
+    if( p_port->p_hwbuf->anwpriv.setBuffersGeometry( p_port->p_hwbuf->window_priv,
+                                                     def->format.video.nFrameWidth,
+                                                     def->format.video.nFrameHeight,
+                                                     colorFormat ) != 0 )
+    {
+        msg_Err( p_dec, "can't set buffers geometry" );
         goto error;
     }
 
-    if( p_port->p_hwbuf->anwpriv.getMinUndequeued( p_port->p_hwbuf->window,
+    if( p_port->p_hwbuf->anwpriv.getMinUndequeued( p_port->p_hwbuf->window_priv,
                                                    &min_undequeued ) != 0 )
     {
         msg_Err( p_dec, "can't get min_undequeued" );
@@ -2230,20 +2252,13 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
                      omx_error, ErrorToString(omx_error) );
     }
 
-    if( p_port->p_hwbuf->anwpriv.setBufferCount( p_port->p_hwbuf->window,
+    if( p_port->p_hwbuf->anwpriv.setBufferCount( p_port->p_hwbuf->window_priv,
                                                  def->nBufferCountActual ) != 0 )
     {
         msg_Err( p_dec, "can't set buffer_count" );
         goto error;
     }
 
-    jni_SetAndroidSurfaceSize( p_port->p_hwbuf->fmt_out.i_width,
-                               p_port->p_hwbuf->fmt_out.i_height,
-                               p_port->p_hwbuf->fmt_out.i_visible_width,
-                               p_port->p_hwbuf->fmt_out.i_visible_height,
-                               p_port->p_hwbuf->fmt_out.i_sar_num,
-                               p_port->p_hwbuf->fmt_out.i_sar_den );
-
     p_port->p_hwbuf->i_buffers = p_port->definition.nBufferCountActual;
     p_port->p_hwbuf->i_max_owned = p_port->p_hwbuf->i_buffers - min_undequeued;
 
@@ -2265,7 +2280,7 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
     {
         void *p_handle = NULL;
 
-        if( p_port->p_hwbuf->anwpriv.dequeue( p_port->p_hwbuf->window,
+        if( p_port->p_hwbuf->anwpriv.dequeue( p_port->p_hwbuf->window_priv,
                                               &p_handle ) != 0 )
         {
             msg_Err( p_dec, "OMXHWBuffer_dequeue Fail" );
@@ -2278,7 +2293,7 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
     for(; i < p_port->p_hwbuf->i_buffers; i++)
     {
         OMX_DBG( "canceling buffer(%d)", i );
-        p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window,
+        p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv,
                                          p_port->p_hwbuf->pp_handles[i] );
     }
 
@@ -2309,7 +2324,7 @@ static int HwBuffer_FreeBuffers( decoder_t *p_dec, OmxPort *p_port )
 
             if( p_handle && p_port->p_hwbuf->i_states[i] == BUF_STATE_OWNED )
             {
-                p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window, p_handle );
+                p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv, p_handle );
                 HwBuffer_ChangeState( p_dec, p_port, i, BUF_STATE_NOT_OWNED );
             }
         }
@@ -2349,7 +2364,7 @@ static int HwBuffer_Start( decoder_t *p_dec, OmxPort *p_port )
 
         if( p_header && p_port->p_hwbuf->i_states[i] == BUF_STATE_OWNED )
         {
-            if( p_port->p_hwbuf->anwpriv.lock( p_port->p_hwbuf->window,
+            if( p_port->p_hwbuf->anwpriv.lock( p_port->p_hwbuf->window_priv,
                                                p_header->pBuffer ) != 0 )
             {
                 msg_Err( p_dec, "lock failed" );
@@ -2396,14 +2411,14 @@ static int HwBuffer_Stop( decoder_t *p_dec, OmxPort *p_port )
             if( p_pic ) {
                 picture_sys_t *p_picsys = p_pic->p_sys;
                 if( p_picsys ) {
-                    void *p_handle = p_port->pp_buffers[p_picsys->i_index]->pBuffer;
+                    void *p_handle = p_port->pp_buffers[p_picsys->priv.hw.i_index]->pBuffer;
                     if( p_handle )
                     {
-                        p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window, p_handle );
-                        HwBuffer_ChangeState( p_dec, p_port, p_picsys->i_index,
+                        p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv, p_handle );
+                        HwBuffer_ChangeState( p_dec, p_port, p_picsys->priv.hw.i_index,
                                               BUF_STATE_NOT_OWNED );
                     }
-                    p_picsys->b_valid = false;
+                    p_picsys->priv.hw.b_valid = false;
                 }
                 p_port->p_hwbuf->inflight_picture[i] = NULL;
             }
@@ -2471,11 +2486,11 @@ static int HwBuffer_GetPic( decoder_t *p_dec, OmxPort *p_port,
     p_pic->date = FromOmxTicks( p_header->nTimeStamp );
 
     p_picsys = p_pic->p_sys;
-    p_picsys->pf_display_callback = DisplayCallback;
-    p_picsys->pf_unlock_callback = UnlockCallback;
-    p_picsys->p_dec = p_dec;
-    p_picsys->i_index = i_index;
-    p_picsys->b_valid = true;
+    p_picsys->pf_lock_pic = NULL;
+    p_picsys->pf_unlock_pic = UnlockPicture;
+    p_picsys->priv.hw.p_dec = p_dec;
+    p_picsys->priv.hw.i_index = i_index;
+    p_picsys->priv.hw.b_valid = true;
 
     HWBUFFER_LOCK();
     p_port->p_hwbuf->inflight_picture[i_index] = p_pic;
@@ -2494,7 +2509,7 @@ static void HwBuffer_SetCrop( decoder_t *p_dec, OmxPort *p_port,
 {
     VLC_UNUSED( p_dec );
 
-    p_port->p_hwbuf->anwpriv.setCrop( p_port->p_hwbuf->window,
+    p_port->p_hwbuf->anwpriv.setCrop( p_port->p_hwbuf->window_priv,
                                       p_rect->nLeft, p_rect->nTop,
                                       p_rect->nWidth, p_rect->nHeight );
 }
@@ -2529,9 +2544,9 @@ static void *DequeueThread( void *data )
         /* The thread can be stuck here. It shouldn't happen since we make sure
          * we call the dequeue function if there is at least one buffer
          * available. */
-        err = p_port->p_hwbuf->anwpriv.dequeue( p_port->p_hwbuf->window, &p_handle );
+        err = p_port->p_hwbuf->anwpriv.dequeue( p_port->p_hwbuf->window_priv, &p_handle );
         if( err == 0 )
-            err = p_port->p_hwbuf->anwpriv.lock( p_port->p_hwbuf->window, p_handle );
+            err = p_port->p_hwbuf->anwpriv.lock( p_port->p_hwbuf->window_priv, p_handle );
 
         HWBUFFER_LOCK();
 
@@ -2543,7 +2558,7 @@ static void *DequeueThread( void *data )
 
         if( !p_port->p_hwbuf->b_run )
         {
-            p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window, p_handle );
+            p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv, p_handle );
             continue;
         }
 
@@ -2578,24 +2593,25 @@ static void *DequeueThread( void *data )
 /*****************************************************************************
  * vout callbacks
  *****************************************************************************/
-static void DisplayBuffer( picture_sys_t* p_picsys, bool b_render )
+static void UnlockPicture( picture_t* p_pic, bool b_render )
 {
-    decoder_t *p_dec = p_picsys->p_dec;
+    picture_sys_t *p_picsys = p_pic->p_sys;
+    decoder_t *p_dec = p_picsys->priv.hw.p_dec;
     decoder_sys_t *p_sys = p_dec->p_sys;
     OmxPort *p_port = &p_sys->out;
     void *p_handle;
 
-    if( !p_picsys->b_valid ) return;
+    if( !p_picsys->priv.hw.b_valid ) return;
 
     HWBUFFER_LOCK();
 
     /* Picture might have been invalidated while waiting on the mutex. */
-    if (!p_picsys->b_valid) {
+    if (!p_picsys->priv.hw.b_valid) {
         HWBUFFER_UNLOCK();
         return;
     }
 
-    p_handle = p_port->pp_buffers[p_picsys->i_index]->pBuffer;
+    p_handle = p_port->pp_buffers[p_picsys->priv.hw.i_index]->pBuffer;
 
     OMX_DBG( "DisplayBuffer: %s %p",
              b_render ? "render" : "cancel", p_handle );
@@ -2607,30 +2623,20 @@ static void DisplayBuffer( picture_sys_t* p_picsys, bool b_render )
     }
 
     if( b_render )
-        p_port->p_hwbuf->anwpriv.queue( p_port->p_hwbuf->window, p_handle );
+        p_port->p_hwbuf->anwpriv.queue( p_port->p_hwbuf->window_priv, p_handle );
     else
-        p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window, p_handle );
+        p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv, p_handle );
 
-    HwBuffer_ChangeState( p_dec, p_port, p_picsys->i_index, BUF_STATE_NOT_OWNED );
+    HwBuffer_ChangeState( p_dec, p_port, p_picsys->priv.hw.i_index, BUF_STATE_NOT_OWNED );
     HWBUFFER_BROADCAST( p_port );
 
-    p_port->p_hwbuf->inflight_picture[p_picsys->i_index] = NULL;
+    p_port->p_hwbuf->inflight_picture[p_picsys->priv.hw.i_index] = NULL;
 
 end:
-    p_picsys->b_valid = false;
-    p_picsys->i_index = -1;
+    p_picsys->priv.hw.b_valid = false;
+    p_picsys->priv.hw.i_index = -1;
 
     HWBUFFER_UNLOCK();
 }
 
-static void UnlockCallback( picture_sys_t* p_picsys )
-{
-    DisplayBuffer( p_picsys, false );
-}
-
-static void DisplayCallback( picture_sys_t* p_picsys )
-{
-    DisplayBuffer( p_picsys, true );
-}
-
 #endif // USE_IOMX