[vlc-devel] [V4 PATCH 4/9] es_out: add ES_OUT_SPU_SET_HIGHLIGHT

Thomas Guillem thomas at gllm.fr
Tue Jul 17 17:00:19 CEST 2018


This control allows demuxers to highlight a specific area of a SPU (already
sent). This will replace the p_input highlight variables and the
VLC_HIGHLIGHT_MUTEX.
---
 include/vlc_es_out.h                |  3 ++
 include/vlc_subpicture.h            | 10 +++++
 src/input/decoder.c                 | 21 ++++++++++
 src/input/decoder.h                 |  2 +-
 src/input/es_out.c                  |  9 +++++
 src/input/es_out_timeshift.c        |  7 ++++
 src/video_output/video_output.c     |  8 ++++
 src/video_output/vout_internal.h    |  3 ++
 src/video_output/vout_subpictures.c | 63 +++++++++--------------------
 9 files changed, 82 insertions(+), 44 deletions(-)

diff --git a/include/vlc_es_out.h b/include/vlc_es_out.h
index 56a014ae8b..30112072a7 100644
--- a/include/vlc_es_out.h
+++ b/include/vlc_es_out.h
@@ -109,6 +109,9 @@ enum es_out_query_e
     ES_OUT_VOUT_FLUSH_OVERLAY, /* arg1= es_out_id_t* (video es),
                                 * arg2= int (channel id), res= can fail */
 
+    ES_OUT_SPU_SET_HIGHLIGHT, /* arg1= es_out_id_t* (spu es),
+                                 arg2= const vlc_spu_highlight_t *, res=can fail  */
+
     /* First value usable for private control */
     ES_OUT_PRIVATE_START = 0x10000,
 };
diff --git a/include/vlc_subpicture.h b/include/vlc_subpicture.h
index ee6752f443..f001df0894 100644
--- a/include/vlc_subpicture.h
+++ b/include/vlc_subpicture.h
@@ -46,6 +46,7 @@
  * Video subtitle region spu core private
  */
 typedef struct subpicture_region_private_t subpicture_region_private_t;
+typedef struct vlc_spu_highlight_t vlc_spu_highlight_t;
 
 /**
  * Video subtitle region
@@ -77,6 +78,15 @@ struct subpicture_region_t
     subpicture_region_private_t *p_private;  /**< Private data for spu_t *only* */
 };
 
+struct vlc_spu_highlight_t
+{
+    int x_start;
+    int x_end;
+    int y_start;
+    int y_end;
+    video_palette_t palette;
+};
+
 /* Subpicture region position flags */
 #define SUBPICTURE_ALIGN_LEFT       0x1
 #define SUBPICTURE_ALIGN_RIGHT      0x2
diff --git a/src/input/decoder.c b/src/input/decoder.c
index 0001078413..d420891f47 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -2530,3 +2530,24 @@ int input_DecoderFlushVoutOverlay( decoder_t *dec, int channel )
     vlc_mutex_unlock( &owner->lock );
     return VLC_SUCCESS;
 }
+
+int input_DecoderSetSpuHighlight( decoder_t *dec,
+                                  const vlc_spu_highlight_t *spu_hl )
+{
+    struct decoder_owner *p_owner = dec_get_owner( dec );
+
+    if( dec->fmt_out.i_cat != SPU_ES )
+        return VLC_EGENERIC;
+
+    vlc_mutex_lock( &p_owner->lock );
+    if( !p_owner->p_vout )
+    {
+        vlc_mutex_unlock( &p_owner->lock );
+        return VLC_EGENERIC;
+    }
+
+    vout_SetSpuHighlight( p_owner->p_vout, spu_hl );
+
+    vlc_mutex_unlock( &p_owner->lock );
+    return VLC_SUCCESS;
+}
diff --git a/src/input/decoder.h b/src/input/decoder.h
index 50e2bf6491..6f4727aa99 100644
--- a/src/input/decoder.h
+++ b/src/input/decoder.h
@@ -118,8 +118,8 @@ size_t input_DecoderGetFifoSize( decoder_t *p_dec );
 void input_DecoderGetObjects( decoder_t *, vout_thread_t **, audio_output_t ** );
 
 int  input_DecoderSetVoutMouseEvent( decoder_t *, vlc_mouse_event, void * );
-
 int  input_DecoderAddVoutOverlay( decoder_t *, subpicture_t *, int * );
 int  input_DecoderFlushVoutOverlay( decoder_t *, int );
+int  input_DecoderSetSpuHighlight( decoder_t *, const vlc_spu_highlight_t * );
 
 #endif
diff --git a/src/input/es_out.c b/src/input/es_out.c
index 740b22d983..6605028e00 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -2900,6 +2900,15 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
         int channel = va_arg( args, int );
         if( p_es && p_es->p_dec )
             return input_DecoderFlushVoutOverlay( p_es->p_dec, channel );
+    }
+    case ES_OUT_SPU_SET_HIGHLIGHT:
+    {
+        es_out_id_t *es = va_arg( args, es_out_id_t * );
+        const vlc_spu_highlight_t *spu_hl =
+            va_arg( args, const vlc_spu_highlight_t * );
+
+        if( es != NULL && es->p_dec )
+            return input_DecoderSetSpuHighlight( es->p_dec, spu_hl );
         return VLC_EGENERIC;
     }
 
diff --git a/src/input/es_out_timeshift.c b/src/input/es_out_timeshift.c
index 9aef9492e5..edf3983c8f 100644
--- a/src/input/es_out_timeshift.c
+++ b/src/input/es_out_timeshift.c
@@ -676,6 +676,13 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args )
         return es_out_Control( p_sys->p_out, ES_OUT_VOUT_FLUSH_OVERLAY,
                                p_es->p_es, channel );
     }
+    case ES_OUT_SPU_SET_HIGHLIGHT:
+    {
+        es_out_id_t *p_es = (es_out_id_t*)va_arg( args, es_out_id_t * );
+        const vlc_spu_highlight_t *p_hl = va_arg( args, const vlc_spu_highlight_t * );
+        return es_out_Control( p_sys->p_out, ES_OUT_SPU_SET_HIGHLIGHT,
+                               p_es->p_es, p_hl );
+    }
     /* Special internal input control */
     case ES_OUT_GET_EMPTY:
     {
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 43e55b163b..fca04e1227 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -398,6 +398,14 @@ void vout_FlushSubpictureChannel( vout_thread_t *vout, int channel )
     vout_control_PushInteger(&vout->p->control, VOUT_CONTROL_FLUSH_SUBPICTURE,
                              channel);
 }
+void vout_SetSpuHighlight( vout_thread_t *vout,
+                        const vlc_spu_highlight_t *spu_hl )
+{
+    vlc_mutex_lock(&vout->p->spu_lock);
+    if (vout->p->spu)
+        spu_SetHighlight(vout->p->spu, spu_hl);
+    vlc_mutex_unlock(&vout->p->spu_lock);
+}
 
 /**
  * Allocates a video output picture buffer.
diff --git a/src/video_output/vout_internal.h b/src/video_output/vout_internal.h
index 155efdf189..1ff5dde454 100644
--- a/src/video_output/vout_internal.h
+++ b/src/video_output/vout_internal.h
@@ -223,6 +223,7 @@ void vout_ManageWrapper(vout_thread_t *);
 int spu_ProcessMouse(spu_t *, const vlc_mouse_t *, const video_format_t *);
 void spu_Attach( spu_t *, vlc_object_t *input, bool );
 void spu_ChangeMargin(spu_t *, int);
+void spu_SetHighlight(spu_t *, const vlc_spu_highlight_t*);
 
 /**
  * This function will (un)pause the display of pictures.
@@ -278,4 +279,6 @@ void vout_DisplayTitle( vout_thread_t *p_vout, const char *psz_title );
  */
 bool vout_IsEmpty( vout_thread_t *p_vout );
 
+void vout_SetSpuHighlight( vout_thread_t *p_vout, const vlc_spu_highlight_t * );
+
 #endif
diff --git a/src/video_output/vout_subpictures.c b/src/video_output/vout_subpictures.c
index e5bcc1555d..e56838c53d 100644
--- a/src/video_output/vout_subpictures.c
+++ b/src/video_output/vout_subpictures.c
@@ -80,8 +80,7 @@ struct spu_private_t {
     } crop;                                                  /**< cropping */
 
     int     margin;                    /**< force position of a subpicture */
-    bool    force_palette;                /**< force palette of subpicture */
-    uint8_t palette[4][4];                             /**< forced palette */
+    video_palette_t palette;              /**< force palette of subpicture */
 
     /* Subpiture filters */
     char           *source_chain_current;
@@ -695,7 +694,7 @@ static void SpuRenderRegion(spu_t *spu,
      * instead of only the right one (being the dvd spu).
      */
     const bool using_palette = region->fmt.i_chroma == VLC_CODEC_YUVP;
-    const bool force_palette = using_palette && sys->force_palette;
+    const bool force_palette = using_palette && sys->palette.i_entries > 0;
     const bool crop_requested = (force_palette && sys->force_crop) ||
                                 region->i_max_width || region->i_max_height;
     bool changed_palette     = false;
@@ -754,7 +753,7 @@ static void SpuRenderRegion(spu_t *spu,
         for (int i = 0; i < 4; i++)
         {
             for (int j = 0; j < 4; j++)
-                new_palette.palette[i][j] = sys->palette[i][j];
+                new_palette.palette[i][j] = sys->palette.palette[i][j];
             b_opaque |= (new_palette.palette[i][3] > 0x00);
         }
 
@@ -1141,55 +1140,35 @@ static subpicture_t *SpuRenderSubpictures(spu_t *spu,
 
 /*****************************************************************************
  * UpdateSPU: update subpicture settings
- *****************************************************************************
- * This function is called from CropCallback and at initialization time, to
- * retrieve crop information from the input.
  *****************************************************************************/
-static void UpdateSPU(spu_t *spu, vlc_object_t *object)
+static void UpdateSPU(spu_t *spu, const vlc_spu_highlight_t *hl)
 {
     spu_private_t *sys = spu->p;
-    vlc_value_t val;
 
     vlc_mutex_lock(&sys->lock);
 
-    sys->force_palette = false;
+    sys->palette.i_entries = 0;
     sys->force_crop = false;
 
-    if (var_Get(object, "highlight", &val) || !val.b_bool) {
+    if (hl == NULL) {
         vlc_mutex_unlock(&sys->lock);
         return;
     }
 
     sys->force_crop = true;
-    sys->crop.x      = var_GetInteger(object, "x-start");
-    sys->crop.y      = var_GetInteger(object, "y-start");
-    sys->crop.width  = var_GetInteger(object, "x-end") - sys->crop.x;
-    sys->crop.height = var_GetInteger(object, "y-end") - sys->crop.y;
-
-    if (var_Get(object, "menu-palette", &val) == VLC_SUCCESS) {
-        memcpy(sys->palette, val.p_address, 16);
-        sys->force_palette = true;
-    }
+    sys->crop.x      = hl->x_start;
+    sys->crop.y      = hl->y_start;
+    sys->crop.width  = hl->x_end - sys->crop.x;
+    sys->crop.height = hl->y_end - sys->crop.y;
+
+    if (hl->palette.i_entries == 4) /* XXX: Only DVD palette for now */
+        memcpy(&sys->palette, &hl->palette, sizeof(sys->palette));
     vlc_mutex_unlock(&sys->lock);
 
-    msg_Dbg(object, "crop: %i,%i,%i,%i, palette forced: %i",
+    msg_Dbg(spu, "crop: %i,%i,%i,%i, palette forced: %i",
             sys->crop.x, sys->crop.y,
             sys->crop.width, sys->crop.height,
-            sys->force_palette);
-}
-
-/*****************************************************************************
- * CropCallback: called when the highlight properties are changed
- *****************************************************************************
- * This callback is called from the input thread when we need cropping
- *****************************************************************************/
-static int CropCallback(vlc_object_t *object, char const *var,
-                        vlc_value_t oldval, vlc_value_t newval, void *data)
-{
-    VLC_UNUSED(oldval); VLC_UNUSED(newval); VLC_UNUSED(var);
-
-    UpdateSPU((spu_t *)data, object);
-    return VLC_SUCCESS;
+            sys->palette.i_entries);
 }
 
 /*****************************************************************************
@@ -1390,9 +1369,7 @@ void spu_Destroy(spu_t *spu)
 void spu_Attach(spu_t *spu, vlc_object_t *input, bool attach)
 {
     if (attach) {
-        UpdateSPU(spu, input);
-        var_Create(input, "highlight", VLC_VAR_BOOL);
-        var_AddCallback(input, "highlight", CropCallback, spu);
+        UpdateSPU(spu, NULL);
 
         vlc_mutex_lock(&spu->p->lock);
         spu->p->input = input;
@@ -1406,10 +1383,6 @@ void spu_Attach(spu_t *spu, vlc_object_t *input, bool attach)
         vlc_mutex_lock(&spu->p->lock);
         spu->p->input = NULL;
         vlc_mutex_unlock(&spu->p->lock);
-
-        /* Delete callbacks */
-        var_DelCallback(input, "highlight", CropCallback, spu);
-        var_Destroy(input, "highlight");
     }
 }
 
@@ -1714,3 +1687,7 @@ void spu_ChangeMargin(spu_t *spu, int margin)
     vlc_mutex_unlock(&sys->lock);
 }
 
+void spu_SetHighlight(spu_t *spu, const vlc_spu_highlight_t *hl)
+{
+    UpdateSPU(spu, hl);
+}
-- 
2.18.0



More information about the vlc-devel mailing list