]> 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 b7a586f28eb1a958adbf5ca8e43efbd07aba60e5..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
@@ -2050,11 +2063,7 @@ static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port )
     msg_Dbg( p_dec, "HwBuffer_Init");
 
     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_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 &&
+          pf_get_hal_format &&
           ((OMX_COMPONENTTYPE*)p_port->omx_handle)->UseBuffer) )
     {
         msg_Warn( p_dec, "direct output port enabled but can't find "
@@ -2074,6 +2083,11 @@ static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port )
         msg_Warn( p_dec, "LoadNativeWindowAPI failed" );
         goto error;
     }
+    if( LoadNativeWindowPrivAPI( &p_port->p_hwbuf->anwpriv ) != 0 )
+    {
+        msg_Warn( p_dec, "LoadNativeWindowPrivAPI failed" );
+        goto error;
+    }
 
     surf = jni_LockAndGetAndroidJavaSurface();
     if( !surf ) {
@@ -2082,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;
     }
-    pf_omx_hwbuffer_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 );
@@ -2126,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 );
-                pf_omx_hwbuffer_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 );
@@ -2157,19 +2178,11 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
     if( !p_port->p_hwbuf )
         return 0;
 
-    if( !strncmp( p_sys->psz_component, "OMX.SEC.", 8 ) ) {
-        switch( colorFormat ) {
-        case OMX_COLOR_FormatYUV420SemiPlanar:
-            colorFormat = 0x105; // HAL_PIXEL_FORMAT_YCbCr_420_SP
-            break;
-        case OMX_COLOR_FormatYUV420Planar:
-            colorFormat = 0x101; // HAL_PIXEL_FORMAT_YCbCr_420_P
-            break;
-        }
+    omx_error = pf_get_hal_format( p_sys->psz_component, &colorFormat );
+    if( omx_error != OMX_ErrorNone )
+    {
+        msg_Warn( p_dec, "pf_get_hal_format failed (Not fatal)" );
     }
-    else if( !strcmp( p_sys->psz_component, "OMX.TI.720P.Decoder" ) ||
-        !strcmp( p_sys->psz_component, "OMX.TI.Video.Decoder" ) )
-        colorFormat = 0x14; // HAL_PIXEL_FORMAT_YCbCr_422_I
 
     omx_error = pf_get_graphic_buffer_usage( p_port->omx_handle,
                                              p_port->i_port_index,
@@ -2180,18 +2193,45 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
         i_hw_usage = 0;
     }
 
-    if( pf_omx_hwbuffer_setup( p_port->p_hwbuf->window,
-                               def->format.video.nFrameWidth,
-                               def->format.video.nFrameHeight,
-                               colorFormat,
-                               (int) i_hw_usage ) != 0 )
+    if( p_port->p_fmt->video.orientation != ORIENT_NORMAL )
     {
-        msg_Err( p_dec, "can't setup OMXHWBuffer" );
+        int i_angle;
+
+        switch( p_port->p_fmt->video.orientation )
+        {
+            case ORIENT_ROTATED_90:
+                i_angle = 90;
+                break;
+            case ORIENT_ROTATED_180:
+                i_angle = 180;
+                break;
+            case ORIENT_ROTATED_270:
+                i_angle = 270;
+                break;
+            default:
+                i_angle = 0;
+        }
+        p_port->p_hwbuf->anwpriv.setOrientation( p_port->p_hwbuf->window_priv,
+                                                 i_angle );
+    }
+
+    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( pf_omx_hwbuffer_get_min_undequeued( p_port->p_hwbuf->window,
-                                            &min_undequeued ) != 0 )
+    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" );
         goto error;
@@ -2212,20 +2252,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 )
+    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( def->format.video.nFrameWidth,
-                               def->format.video.nFrameHeight,
-                               def->format.video.nFrameWidth,
-                               def->format.video.nFrameHeight,
-                               p_dec->fmt_out.video.i_sar_num,
-                               p_dec->fmt_out.video.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;
 
@@ -2247,7 +2280,8 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
     {
         void *p_handle = NULL;
 
-        if( pf_omx_hwbuffer_dequeue( p_port->p_hwbuf->window, &p_handle ) != 0 )
+        if( p_port->p_hwbuf->anwpriv.dequeue( p_port->p_hwbuf->window_priv,
+                                              &p_handle ) != 0 )
         {
             msg_Err( p_dec, "OMXHWBuffer_dequeue Fail" );
             goto error;
@@ -2259,8 +2293,8 @@ 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 );
-        pf_omx_hwbuffer_cancel( p_port->p_hwbuf->window,
-                                p_port->p_hwbuf->pp_handles[i] );
+        p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv,
+                                         p_port->p_hwbuf->pp_handles[i] );
     }
 
     return 0;
@@ -2290,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 )
             {
-                pf_omx_hwbuffer_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 );
             }
         }
@@ -2330,8 +2364,8 @@ 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( pf_omx_hwbuffer_lock( p_port->p_hwbuf->window,
-                                      p_header->pBuffer ) != 0 )
+            if( p_port->p_hwbuf->anwpriv.lock( p_port->p_hwbuf->window_priv,
+                                               p_header->pBuffer ) != 0 )
             {
                 msg_Err( p_dec, "lock failed" );
                 HWBUFFER_UNLOCK();
@@ -2358,7 +2392,7 @@ static int HwBuffer_Start( decoder_t *p_dec, OmxPort *p_port )
 
 /*****************************************************************************
  * HwBuffer_Stop: stop DequeueThread and invalidate all pictures that are sent
- * to vlc core. The thread can be stuck in pf_omx_hwbuffer_dequeue, so don't
+ * to vlc core. The thread can be stuck in dequeue, so don't
  * join it now since it can be unblocked later by HwBuffer_FreeBuffers.
  *****************************************************************************/
 static int HwBuffer_Stop( decoder_t *p_dec, OmxPort *p_port )
@@ -2377,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 )
                     {
-                        pf_omx_hwbuffer_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;
             }
@@ -2452,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;
@@ -2475,9 +2509,9 @@ static void HwBuffer_SetCrop( decoder_t *p_dec, OmxPort *p_port,
 {
     VLC_UNUSED( p_dec );
 
-    pf_omx_hwbuffer_setcrop( p_port->p_hwbuf->window,
-                             p_rect->nLeft, p_rect->nTop,
-                             p_rect->nWidth, p_rect->nHeight );
+    p_port->p_hwbuf->anwpriv.setCrop( p_port->p_hwbuf->window_priv,
+                                      p_rect->nLeft, p_rect->nTop,
+                                      p_rect->nWidth, p_rect->nHeight );
 }
 
 /*****************************************************************************
@@ -2510,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 = pf_omx_hwbuffer_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 = pf_omx_hwbuffer_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();
 
@@ -2524,7 +2558,7 @@ static void *DequeueThread( void *data )
 
         if( !p_port->p_hwbuf->b_run )
         {
-            pf_omx_hwbuffer_cancel( p_port->p_hwbuf->window, p_handle );
+            p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv, p_handle );
             continue;
         }
 
@@ -2539,7 +2573,7 @@ static void *DequeueThread( void *data )
         }
         if( i_index == -1 )
         {
-            msg_Err( p_dec, "pf_omx_hwbuffer_dequeue returned unknown handle" );
+            msg_Err( p_dec, "p_port->p_hwbuf->anwpriv.dequeue returned unknown handle" );
             continue;
         }
 
@@ -2559,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 );
@@ -2588,30 +2623,20 @@ static void DisplayBuffer( picture_sys_t* p_picsys, bool b_render )
     }
 
     if( b_render )
-        pf_omx_hwbuffer_queue( p_port->p_hwbuf->window, p_handle );
+        p_port->p_hwbuf->anwpriv.queue( p_port->p_hwbuf->window_priv, p_handle );
     else
-        pf_omx_hwbuffer_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