codec: omxil/android: get the native surface from the vout
authorThomas Guillem <thomas@gllm.fr>
Tue, 22 Nov 2016 17:23:49 +0000 (18:23 +0100)
committerThomas Guillem <thomas@gllm.fr>
Mon, 28 Nov 2016 15:36:44 +0000 (16:36 +0100)
modules/codec/omxil/mediacodec.c
modules/codec/omxil/mediacodec.h
modules/codec/omxil/mediacodec_jni.c
modules/codec/omxil/mediacodec_ndk.c
modules/codec/omxil/omxil.c
modules/codec/omxil/omxil.h
modules/video_output/android/display.c
modules/video_output/android/display.h

index 605f4c7..225cd52 100644 (file)
@@ -115,7 +115,6 @@ struct decoder_sys_t
     {
         struct
         {
-            AWindowHandler *p_awh;
             unsigned int i_stride, i_slice_height, i_width, i_height;
             int i_pixel_format;
             uint8_t i_nal_length_size;
@@ -486,6 +485,7 @@ static int ParseVideoExtra(decoder_t *p_dec)
 static int StartMediaCodec(decoder_t *p_dec)
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
+    picture_t *p_dummy_hwpic = NULL;
     union mc_api_args args;
 
     if (((p_sys->api->i_quirks & MC_API_QUIRKS_NEED_CSD) && !p_sys->pp_csd))
@@ -535,30 +535,29 @@ static int StartMediaCodec(decoder_t *p_dec)
             }
         }
 
-        if (!p_sys->u.video.p_awh && var_InheritBool(p_dec, CFG_PREFIX "dr"))
+        if (var_InheritBool(p_dec, CFG_PREFIX "dr"))
         {
-            if ((p_sys->u.video.p_awh = AWindowHandler_new(VLC_OBJECT(p_dec))))
-            {
-                /* Direct rendering:
-                 * The surface must be released by the Vout before calling
-                 * start. Request a valid OPAQUE Vout to release any non-OPAQUE
-                 * Vout that will release the surface.
-                 */
-                p_dec->fmt_out.video.i_width = p_sys->u.video.i_width;
-                p_dec->fmt_out.video.i_height = p_sys->u.video.i_height;
-                p_dec->fmt_out.i_codec = VLC_CODEC_ANDROID_OPAQUE;
-                if (decoder_UpdateVideoFormat(p_dec) != 0)
-                {
-                    msg_Err(p_dec, "Opaque Vout request failed: "
-                                   "fallback to non opaque");
-
-                    AWindowHandler_destroy(p_sys->u.video.p_awh);
-                    p_sys->u.video.p_awh = NULL;
-                }
-            }
+            /* Direct rendering: Request a valid OPAQUE Vout in order to get
+             * the surface attached to it */
+            p_dec->fmt_out.video.i_width = p_sys->u.video.i_width;
+            p_dec->fmt_out.video.i_height = p_sys->u.video.i_height;
+            p_dec->fmt_out.i_codec = VLC_CODEC_ANDROID_OPAQUE;
+            if (decoder_UpdateVideoFormat(p_dec) != 0
+             || (p_dummy_hwpic = decoder_NewPicture(p_dec)) == NULL)
+                msg_Err(p_dec, "Opaque Vout request failed: "
+                               "fallback to non opaque");
+        }
+        if (p_dummy_hwpic)
+        {
+            assert(p_dummy_hwpic->p_sys);
+            assert(p_dummy_hwpic->p_sys->priv.hw.p_surface);
+            assert(p_dummy_hwpic->p_sys->priv.hw.p_jsurface);
+            args.video.p_surface = p_dummy_hwpic->p_sys->priv.hw.p_surface;
+            args.video.p_jsurface = p_dummy_hwpic->p_sys->priv.hw.p_jsurface;
         }
-        args.video.p_awh = p_sys->u.video.p_awh;
-        args.video.b_tunneled_playback = args.video.p_awh ?
+        else
+            args.video.p_surface = args.video.p_jsurface = NULL;
+        args.video.b_tunneled_playback = args.video.p_surface ?
                 var_InheritBool(p_dec, CFG_PREFIX "tunneled-playback") : false;
     }
     else
@@ -569,7 +568,10 @@ static int StartMediaCodec(decoder_t *p_dec)
         args.audio.i_channel_count  = p_dec->p_sys->u.audio.i_channels;
     }
 
-    return p_sys->api->start(p_sys->api, &args);
+    int i_ret = p_sys->api->start(p_sys->api, &args);
+    if (p_dummy_hwpic != NULL)
+        picture_Release(p_dummy_hwpic);
+    return i_ret;
 }
 
 /*****************************************************************************
@@ -585,9 +587,6 @@ static void StopMediaCodec(decoder_t *p_dec)
         RemoveInflightPictures(p_dec);
 
     p_sys->api->stop(p_sys->api);
-    if (p_dec->fmt_in.i_cat == VIDEO_ES && p_sys->u.video.p_awh)
-        AWindowHandler_releaseANativeWindow(p_sys->u.video.p_awh, AWindow_Video,
-                                            true);
 }
 
 /*****************************************************************************
@@ -867,8 +866,6 @@ static void CleanDecoder(decoder_t *p_dec)
     {
         if (p_sys->u.video.timestamp_fifo)
             timestamp_FifoRelease(p_sys->u.video.timestamp_fifo);
-        if (p_sys->u.video.p_awh)
-            AWindowHandler_destroy(p_sys->u.video.p_awh);
     }
     free(p_sys->api);
     free(p_sys);
index e68b66f..c130069 100644 (file)
@@ -87,7 +87,8 @@ union mc_api_args
 {
     struct
     {
-        AWindowHandler *p_awh;
+        void *p_surface;
+        void *p_jsurface;
         int i_width;
         int i_height;
         int i_angle;
index 66fd122..a2b276f 100644 (file)
@@ -536,9 +536,7 @@ static int Start(mc_api *api, union mc_api_args *p_args)
                                                  jmime,
                                                  p_args->video.i_width,
                                                  p_args->video.i_height);
-        if (p_args->video.p_awh)
-            jsurface = AWindowHandler_getSurface(p_args->video.p_awh,
-                                                 AWindow_Video);
+        jsurface = p_args->video.p_jsurface;
         b_direct_rendering = !!jsurface;
 
         /* There is no way to rotate the video using direct rendering (and
index 4c23966..c7a25ae 100644 (file)
@@ -332,11 +332,10 @@ static int Start(mc_api *api, union mc_api_args *p_args)
         syms.AMediaFormat.setInt32(p_sys->p_format, "width", p_args->video.i_width);
         syms.AMediaFormat.setInt32(p_sys->p_format, "height", p_args->video.i_height);
         syms.AMediaFormat.setInt32(p_sys->p_format, "rotation-degrees", p_args->video.i_angle);
-        if (p_args->video.p_awh)
+        if (p_args->video.p_surface)
         {
-            p_anw = AWindowHandler_getANativeWindow(p_args->video.p_awh,
-                                                    AWindow_Video);
-            if( p_anw )
+            p_anw = p_args->video.p_surface;
+            if (p_args->video.b_tunneled_playback)
                 syms.AMediaFormat.setInt32(p_sys->p_format,
                                            "feature-tunneled-playback",
                                            p_args->video.b_tunneled_playback);
index 3e071a3..47d0e19 100644 (file)
@@ -2051,8 +2051,8 @@ static void HwBuffer_ChangeState( decoder_t *p_dec, OmxPort *p_port,
 static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port )
 {
     VLC_UNUSED( p_dec );
-    ANativeWindow *p_anw;
     OMX_ERRORTYPE omx_error;
+    picture_t *p_dummy_hwpic = NULL;
 
     if( !p_port->b_direct || p_port->definition.eDir != OMX_DirOutput ||
         p_port->p_fmt->i_cat != VIDEO_ES )
@@ -2069,6 +2069,17 @@ static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port )
         goto error;
     }
 
+    p_dec->fmt_out.i_codec = VLC_CODEC_ANDROID_OPAQUE;
+    if (decoder_UpdateVideoFormat(p_dec) != 0
+     || (p_dummy_hwpic = decoder_NewPicture(p_dec)) == NULL)
+    {
+        msg_Err(p_dec, "Opaque Vout request failed");
+        goto error;
+    }
+    ANativeWindow *p_anw = p_dummy_hwpic->p_sys->priv.hw.p_surface;
+    if( !p_anw )
+        goto error;
+
     p_port->p_hwbuf = calloc(1, sizeof(HwBuffer));
     if( !p_port->p_hwbuf )
     {
@@ -2077,24 +2088,11 @@ static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port )
     vlc_mutex_init (&p_port->p_hwbuf->lock);
     vlc_cond_init (&p_port->p_hwbuf->wait);
 
-    p_port->p_hwbuf->p_awh = AWindowHandler_new( VLC_OBJECT( p_dec ) );
-    if( !p_port->p_hwbuf->p_awh )
-    {
-        msg_Warn( p_dec, "AWindowHandler_new failed" );
-        goto error;
-    }
     if( android_loadNativeWindowPrivApi( &p_port->p_hwbuf->anwpriv ) )
     {
         msg_Warn( p_dec, "android_loadNativeWindowPrivApi failed" );
         goto error;
     }
-    p_anw = AWindowHandler_getANativeWindow( p_port->p_hwbuf->p_awh,
-                                             AWindow_Video );
-    if( !p_anw )
-    {
-        msg_Warn( p_dec, "AWindowHandler_getVideoANativeWindow failed" );
-        goto error;
-    }
 
     p_port->p_hwbuf->window_priv = p_port->p_hwbuf->anwpriv.connect( p_anw );
     if( !p_port->p_hwbuf->window_priv ) {
@@ -2115,8 +2113,12 @@ static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port )
 
 
     msg_Dbg( p_dec, "direct output port enabled" );
+    if (p_dummy_hwpic != NULL)
+        picture_Release(p_dummy_hwpic);
     return;
 error:
+    if (p_dummy_hwpic != NULL)
+        picture_Release(p_dummy_hwpic);
     /* if HwBuffer_Init fails, we can fall back to non direct buffers */
     HwBuffer_Destroy( p_dec, p_port );
 }
@@ -2137,11 +2139,6 @@ static void HwBuffer_Destroy( decoder_t *p_dec, OmxPort *p_port )
             pf_enable_graphic_buffers( p_port->omx_handle,
                                        p_port->i_port_index, OMX_FALSE );
         }
-        if( p_port->p_hwbuf->p_awh )
-        {
-            AWindowHandler_destroy( p_port->p_hwbuf->p_awh );
-            p_port->p_hwbuf->p_awh = NULL;
-        }
 
         vlc_cond_destroy( &p_port->p_hwbuf->wait );
         vlc_mutex_destroy( &p_port->p_hwbuf->lock );
index 74a3621..66b75a4 100644 (file)
@@ -76,7 +76,6 @@ typedef struct HwBuffer
     unsigned int    i_owned;
 
 #if defined(USE_IOMX)
-    AWindowHandler *p_awh;
     native_window_priv_api_t anwpriv;
     native_window_priv *window_priv;
 #endif
index 7d9f9f3..16ab0c0 100644 (file)
@@ -93,6 +93,7 @@ struct android_window
 
     enum AWindow_ID id;
     ANativeWindow *p_surface;
+    jobject       *p_jsurface;
     native_window_priv *p_surface_priv;
 };
 
@@ -214,6 +215,8 @@ static picture_t *PictureAlloc(vout_display_sys_t *sys, video_format_t *fmt,
 
     if (b_opaque)
     {
+        p_picsys->priv.hw.p_surface = sys->p_window->p_surface;
+        p_picsys->priv.hw.p_jsurface =  sys->p_window->p_jsurface;
         p_picsys->priv.hw.i_index = -1;
         vlc_mutex_init(&p_picsys->priv.hw.lock);
         rsc.pf_destroy = AndroidOpaquePicture_DetachVout;
@@ -345,11 +348,14 @@ static void AndroidWindow_DisconnectSurface(vout_display_sys_t *sys,
 static int AndroidWindow_ConnectSurface(vout_display_sys_t *sys,
                                         android_window *p_window)
 {
-    if (!p_window->p_surface && !p_window->b_opaque) {
+    if (!p_window->p_surface) {
         p_window->p_surface = AWindowHandler_getANativeWindow(sys->p_awh,
                                                               p_window->id);
         if (!p_window->p_surface)
             return -1;
+        if (p_window->b_opaque)
+            p_window->p_jsurface = AWindowHandler_getSurface(sys->p_awh,
+                                                             p_window->id);
     }
 
     return 0;
index 8d2b971..ab9d9da 100644 (file)
@@ -42,6 +42,9 @@ struct picture_sys_t
 
     union {
         struct {
+            void *p_surface;
+            void *p_jsurface;
+
             vlc_mutex_t lock;
             decoder_t *p_dec;
             int i_index;