]> git.sesse.net Git - vlc/blobdiff - src/video_output/vout_subpictures.c
Merge commit 'origin/1.0-bugfix'
[vlc] / src / video_output / vout_subpictures.c
index d20d4e04543ff3ffbf0337d83cb631ec8fa32bf3..84ac9996fee7792978c0492e72e982dc478b59aa 100644 (file)
 /* Number of simultaneous subpictures */
 #define VOUT_MAX_SUBPICTURES (VOUT_MAX_PICTURES)
 
-#define VLC_FOURCC_YUVP VLC_FOURCC('Y','U','V','P')
-#define VLC_FOURCC_YUVA VLC_FOURCC('Y','U','V','A')
-#define VLC_FOURCC_RGBA VLC_FOURCC('R','G','B','A')
-#define VLC_FOURCC_TEXT VLC_FOURCC('T','E','X','T')
-
 /* */
 typedef struct
 {
@@ -90,6 +85,7 @@ struct spu_private_t
     uint8_t palette[4][4];                               /**< forced palette */
 
     /* Subpiture filters */
+    char           *psz_chain_update;
     filter_chain_t *p_chain;
 
     /* */
@@ -168,8 +164,6 @@ static void spu_del_buffer( filter_t *, subpicture_t * );
 static picture_t *spu_new_video_buffer( filter_t * );
 static void spu_del_video_buffer( filter_t *, picture_t * );
 
-static int spu_ParseChain( spu_t * );
-
 /* Buffer aloccation fir SUB filter */
 static int SubFilterCallback( vlc_object_t *, char const *,
                               vlc_value_t, vlc_value_t, void * );
@@ -221,6 +215,7 @@ spu_t *__spu_Create( vlc_object_t *p_this )
 
     vlc_object_attach( p_spu, p_this );
 
+    p_sys->psz_chain_update = NULL;
     p_sys->p_chain = filter_chain_New( p_spu, "sub filter", false,
                                        SubFilterAllocationInit,
                                        SubFilterAllocationClean,
@@ -250,27 +245,11 @@ int spu_Init( spu_t *p_spu )
 
     var_Create( p_spu, "sub-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
     var_AddCallback( p_spu, "sub-filter", SubFilterCallback, p_spu );
-
-    spu_ParseChain( p_spu );
+    var_TriggerCallback( p_spu, "sub-filter" );
 
     return VLC_SUCCESS;
 }
 
-int spu_ParseChain( spu_t *p_spu )
-{
-    char *psz_parser = var_GetString( p_spu, "sub-filter" );
-    int i_ret;
-
-    if( !psz_parser )
-        return VLC_EGENERIC;
-
-    i_ret = filter_chain_AppendFromString( p_spu->p->p_chain, psz_parser );
-
-    free( psz_parser );
-
-    return i_ret;
-}
-
 /**
  * Destroy the subpicture unit
  *
@@ -280,6 +259,8 @@ void spu_Destroy( spu_t *p_spu )
 {
     spu_private_t *p_sys = p_spu->p;
 
+    var_DelCallback( p_spu, "sub-filter", SubFilterCallback, p_spu );
+
     if( p_sys->p_blend )
         FilterRelease( p_sys->p_blend );
 
@@ -293,6 +274,7 @@ void spu_Destroy( spu_t *p_spu )
         FilterRelease( p_sys->p_scale );
 
     filter_chain_Delete( p_sys->p_chain );
+    free( p_sys->psz_chain_update );
 
     /* Destroy all remaining subpictures */
     SpuHeapClean( &p_sys->heap );
@@ -313,7 +295,8 @@ void spu_Attach( spu_t *p_spu, vlc_object_t *p_this, bool b_attach )
     vlc_object_t *p_input;
 
     p_input = vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_PARENT );
-    if( !p_input ) return;
+    if( !p_input )
+        return;
 
     if( b_attach )
     {
@@ -564,6 +547,21 @@ subpicture_t *spu_SortSubpictures( spu_t *p_spu, mtime_t display_date,
     int i_channel;
     subpicture_t *p_subpic = NULL;
 
+    /* Update sub-filter chain */
+    vlc_mutex_lock( &p_sys->lock );
+    char *psz_chain_update = p_sys->psz_chain_update;
+    p_sys->psz_chain_update = NULL;
+    vlc_mutex_unlock( &p_sys->lock );
+
+    if( psz_chain_update )
+    {
+        filter_chain_Reset( p_sys->p_chain, NULL, NULL );
+
+        filter_chain_AppendFromString( p_spu->p->p_chain, psz_chain_update );
+
+        free( psz_chain_update );
+    }
+
     /* Run subpicture filters */
     filter_chain_SubFilter( p_sys->p_chain, display_date );
 
@@ -732,7 +730,7 @@ subpicture_region_t *subpicture_region_New( const video_format_t *p_fmt )
 
     p_region->fmt = *p_fmt;
     p_region->fmt.p_palette = NULL;
-    if( p_fmt->i_chroma == VLC_FOURCC_YUVP )
+    if( p_fmt->i_chroma == VLC_CODEC_YUVP )
     {
         p_region->fmt.p_palette = calloc( 1, sizeof(*p_region->fmt.p_palette) );
         if( p_fmt->p_palette )
@@ -745,7 +743,7 @@ subpicture_region_t *subpicture_region_New( const video_format_t *p_fmt )
     p_region->p_style = NULL;
     p_region->p_picture = NULL;
 
-    if( p_fmt->i_chroma == VLC_FOURCC_TEXT )
+    if( p_fmt->i_chroma == VLC_CODEC_TEXT )
         return p_region;
 
     p_region->p_picture = picture_New( p_fmt->i_chroma, p_fmt->i_width, p_fmt->i_height,
@@ -776,7 +774,8 @@ void subpicture_region_Delete( subpicture_region_t *p_region )
 
     free( p_region->psz_text );
     free( p_region->psz_html );
-    //free( p_region->p_style ); FIXME --fenrir plugin does not allocate the memory for it. I think it might lead to segfault, video renderer can live longer than the decoder
+    if( p_region->p_style )
+        text_style_Delete( p_region->p_style );
     free( p_region );
 }
 
@@ -1032,11 +1031,11 @@ static void SpuRenderCreateAndLoadScale( spu_t *p_spu )
     /* XXX p_spu->p_scale is used for all conversion/scaling except yuvp to
      * yuva/rgba */
     p_spu->p->p_scale = CreateAndLoadScale( VLC_OBJECT(p_spu),
-                                            VLC_FOURCC_YUVA, VLC_FOURCC_YUVA, true );
+                                            VLC_CODEC_YUVA, VLC_CODEC_YUVA, true );
     /* This one is used for YUVP to YUVA/RGBA without scaling
      * FIXME rename it */
     p_spu->p->p_scale_yuvp = CreateAndLoadScale( VLC_OBJECT(p_spu),
-                                                 VLC_FOURCC_YUVP, VLC_FOURCC_YUVA, false );
+                                                 VLC_CODEC_YUVP, VLC_CODEC_YUVA, false );
 }
 
 static void SpuRenderText( spu_t *p_spu, bool *pb_rerender_text,
@@ -1045,7 +1044,7 @@ static void SpuRenderText( spu_t *p_spu, bool *pb_rerender_text,
 {
     filter_t *p_text = p_spu->p->p_text;
 
-    assert( p_region->fmt.i_chroma == VLC_FOURCC_TEXT );
+    assert( p_region->fmt.i_chroma == VLC_CODEC_TEXT );
 
     if( !p_text || !p_text->p_module )
         goto exit;
@@ -1350,14 +1349,14 @@ static void SpuRenderRegion( spu_t *p_spu,
     *p_area = spu_area_create( 0,0, 0,0, scale_size );
 
     /* Render text region */
-    if( p_region->fmt.i_chroma == VLC_FOURCC_TEXT )
+    if( p_region->fmt.i_chroma == VLC_CODEC_TEXT )
     {
         const int i_min_scale_ratio = SCALE_UNIT; /* FIXME what is the right value? (scale_size is not) */
         SpuRenderText( p_spu, &b_rerender_text, p_subpic, p_region, i_min_scale_ratio );
         b_restore_format = b_rerender_text;
 
         /* Check if the rendering has failed ... */
-        if( p_region->fmt.i_chroma == VLC_FOURCC_TEXT )
+        if( p_region->fmt.i_chroma == VLC_CODEC_TEXT )
             goto exit;
     }
 
@@ -1365,7 +1364,7 @@ static void SpuRenderRegion( spu_t *p_spu,
      * FIXME b_force_palette and b_force_crop are applied to all subpictures using palette
      * instead of only the right one (being the dvd spu).
      */
-    const bool b_using_palette = p_region->fmt.i_chroma == VLC_FOURCC_YUVP;
+    const bool b_using_palette = p_region->fmt.i_chroma == VLC_CODEC_YUVP;
     const bool b_force_palette = b_using_palette && p_sys->b_force_palette;
     const bool b_force_crop    = b_force_palette && p_sys->b_force_crop;
     bool b_changed_palette     = false;
@@ -1480,7 +1479,7 @@ static void SpuRenderRegion( spu_t *p_spu,
 
                 /* TODO converting to RGBA for RGB video output is better */
                 p_scale_yuvp->fmt_out.video = p_region->fmt;
-                p_scale_yuvp->fmt_out.video.i_chroma = VLC_FOURCC_YUVA;
+                p_scale_yuvp->fmt_out.video.i_chroma = VLC_CODEC_YUVA;
 
                 p_picture = p_scale_yuvp->pf_video_filter( p_scale_yuvp, p_picture );
                 if( !p_picture )
@@ -1673,7 +1672,9 @@ static void SpuClearChannel( spu_t *p_spu, int i_channel )
         spu_heap_entry_t *p_entry = &p_sys->heap.p_entry[i_subpic];
         subpicture_t *p_subpic = p_entry->p_subpicture;
 
-        if( !p_subpic || p_subpic->i_channel != i_channel )
+        if( !p_subpic )
+            continue;
+        if( p_subpic->i_channel != i_channel && ( i_channel != -1 || p_subpic->i_channel == DEFAULT_CHAN ) )
             continue;
 
         /* You cannot delete subpicture outside of spu_SortSubpictures */
@@ -1854,12 +1855,13 @@ static int SubFilterCallback( vlc_object_t *p_object, char const *psz_var,
     spu_t *p_spu = p_data;
     spu_private_t *p_sys = p_spu->p;
 
-    VLC_UNUSED(p_object); VLC_UNUSED(oldval);
-    VLC_UNUSED(newval); VLC_UNUSED(psz_var);
+    VLC_UNUSED(p_object); VLC_UNUSED(oldval); VLC_UNUSED(psz_var);
 
     vlc_mutex_lock( &p_sys->lock );
-    filter_chain_Reset( p_sys->p_chain, NULL, NULL );
-    spu_ParseChain( p_spu );
+
+    free( p_sys->psz_chain_update );
+    p_sys->psz_chain_update = strdup( newval.psz_string );
+
     vlc_mutex_unlock( &p_sys->lock );
     return VLC_SUCCESS;
 }