瀏覽代碼

es_out: add ES_OUT_SPU_SET_HIGHLIGHT

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.
Thomas Guillem 7 年之前
父節點
當前提交
d9abee2178

+ 3 - 0
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,
 };

+ 10 - 0
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

+ 19 - 0
src/input/decoder.c

@@ -2523,3 +2523,22 @@ 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 );
+    assert( dec->fmt_out.i_cat == SPU_ES );
+
+    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;
+}

+ 1 - 1
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 ** );
 
 void 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

+ 9 - 0
src/input/es_out.c

@@ -2958,6 +2958,15 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args )
             return input_DecoderFlushVoutOverlay( p_es->p_dec, channel );
         return VLC_EGENERIC;
     }
+    case ES_OUT_SPU_SET_HIGHLIGHT:
+    {
+        es_out_id_t *p_es = va_arg( args, es_out_id_t * );
+        const vlc_spu_highlight_t *spu_hl =
+            va_arg( args, const vlc_spu_highlight_t * );
+        if( p_es && p_es->fmt.i_cat == SPU_ES && p_es->p_dec )
+            return input_DecoderSetSpuHighlight( p_es->p_dec, spu_hl );
+        return VLC_EGENERIC;
+    }
 
     default:
         msg_Err( p_sys->p_input, "unknown query 0x%x in %s", i_query,

+ 7 - 0
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:
     {

+ 8 - 0
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.

+ 3 - 0
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

+ 20 - 43
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);
+}