[vlc-devel] [PATCH 10/12] bluray: Adding support for overlay updates.

Hugo Beauzée-Luyssen beauze.h at gmail.com
Sun Jan 22 00:31:05 CET 2012


---
 modules/access/bluray.c |   61 +++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/modules/access/bluray.c b/modules/access/bluray.c
index 2e8ff88..7f082a8 100644
--- a/modules/access/bluray.c
+++ b/modules/access/bluray.c
@@ -70,6 +70,13 @@ vlc_module_end ()
 //libbluray's overlay.h defines 2 types of overlay.
 #define MAX_OVERLAY 2
 
+typedef enum    OverlayStatus
+{
+    Closed = 0,
+    ToDisplay,
+    Displayed
+}               OverlayStatus;
+
 struct demux_sys_t
 {
     BLURAY         *bluray;
@@ -81,6 +88,7 @@ struct demux_sys_t
 
     /* Overlay stuff */
     subpicture_t    *p_pic[MAX_OVERLAY];
+    OverlayStatus   overlay_status[MAX_OVERLAY];
     int             current_overlay; // -1 if no current overlay;
 
     input_thread_t  *p_input;
@@ -286,6 +294,7 @@ static void blurayDeleteOverlaySubPic( demux_t *p_demux, int i_plane )
 {
     demux_sys_t     *p_sys = p_demux->p_sys;
 
+    p_sys->overlay_status[i_plane] = Closed;
     if ( p_sys->p_pic[i_plane] == NULL )
         return ;
     if ( p_sys->p_vout )
@@ -314,12 +323,20 @@ static void blurayCloseOverlay( demux_t *p_demux )
 static void blurayActivateOverlay( demux_t *p_demux, const BD_OVERLAY* const ov )
 {
     demux_sys_t     *p_sys = p_demux->p_sys;
+
+    /*
+     * If the overlay is already displayed, updating regions is enough.
+     * No need for anything else.
+     */
+    if ( p_sys->overlay_status[ov->plane] == Displayed && p_sys->p_vout )
+        return ;
     /*
      * Mark the overlay as available, but don't display it right now.
      * the blurayDemuxMenu will send it to vout, as it may be unavailable when
      * the overlay is computed
      */
     p_sys->current_overlay = ov->plane;
+    p_sys->overlay_status[ov->plane] = ToDisplay;
 }
 
 static void blurayInitOverlay( demux_t *p_demux, const BD_OVERLAY* const ov )
@@ -381,15 +398,48 @@ static void blurayDrawOverlay( demux_t *p_demux, const BD_OVERLAY* const ov )
             }
         }
         //Append the new region at the end of our current regions:
+        //If there's no region yet, don't bother checking for update...
         subpicture_region_t *p_reg = p_sys->p_pic[ov->plane]->p_region;
         if ( p_reg == NULL )
         {
             p_sys->p_pic[ov->plane]->p_region = region;
             return ;
         }
-        while ( p_reg && p_reg->p_next )
-            p_reg = p_reg->p_next;
-        p_reg->p_next = region;
+        /*
+         * While adding the region, check if any region matches the one we're drawing.
+         * if so, delete the old region, and add the new one at the back of the list.
+         */
+        subpicture_region_t *p_prev = NULL;
+        while ( p_reg )
+        {
+            if ( p_reg->i_x == region->i_x && p_reg->i_y == region->i_y &&
+                 p_reg->fmt.i_width == region->fmt.i_width &&
+                 p_reg->fmt.i_height == region->fmt.i_height )
+            {
+                if ( p_prev == NULL )
+                {
+                    p_sys->p_pic[ov->plane]->p_region = p_reg->p_next;
+                    subpicture_region_Delete( p_reg );
+                    p_reg = p_sys->p_pic[ov->plane]->p_region;
+                }
+                else
+                {
+                    p_prev->p_next = p_reg->p_next;
+                    subpicture_region_Delete( p_reg );
+                    p_reg = p_prev->p_next;
+                }
+            }
+            else
+            {
+                p_prev = p_reg;
+                p_reg = p_reg->p_next;
+            }
+        }
+        /* If there's only one region, both prev and reg will be NULL */
+        if ( p_prev == NULL )
+            p_sys->p_pic[ov->plane]->p_region = region;
+        else
+            p_prev->p_next = region;
     }
 }
 
@@ -462,7 +512,7 @@ static void blurayDisplayOverlay( demux_t *p_demux )
     p_sys->p_pic[p_sys->current_overlay]->i_channel =
             vout_RegisterSubpictureChannel( p_sys->p_vout );
     vout_PutSubpicture( p_sys->p_vout, p_sys->p_pic[p_sys->current_overlay] );
-    p_sys->current_overlay = -1;
+    p_sys->overlay_status[p_sys->current_overlay] = Displayed;
     //Activating vout events handling:
     var_AddCallback( p_sys->p_vout, "mouse-moved", &onMouseEvent, p_demux );
     var_AddCallback( p_sys->p_vout, "mouse-clicked", &onMouseEvent, p_demux );
@@ -781,7 +831,8 @@ static int blurayDemuxMenu( demux_t *p_demux )
     }
     p_block->i_buffer = nread;
 
-    if ( p_sys->current_overlay != -1 )
+    if ( p_sys->current_overlay != -1 &&
+         p_sys->overlay_status[p_sys->current_overlay] == ToDisplay )
     {
         if ( p_sys->p_vout == NULL )
             p_sys->p_vout = input_GetVout( p_sys->p_input );
-- 
1.7.8.4




More information about the vlc-devel mailing list