[vlc-commits] [Git][videolan/vlc][master] 6 commits: freetype: allocate the YUVP palette early

Steve Lhomme (@robUx4) gitlab at videolan.org
Fri Nov 10 16:56:31 UTC 2023



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
569c1d03 by Steve Lhomme at 2023-11-10T16:28:30+00:00
freetype: allocate the YUVP palette early

- - - - -
fe415420 by Steve Lhomme at 2023-11-10T16:28:30+00:00
vlc_filter: return a non-text subpicture region when rendering text regions

We no longer need to ugly hack that marks the output region as marked
and we don't mix the input and output regions.

- - - - -
7261e7a0 by Steve Lhomme at 2023-11-10T16:28:30+00:00
freetype: do not use the input region palette

The input region is a text region, it should not have a palette. We would
overwrite the input palette with out own values!
subpicture_region_New() takes care of creating a palette if the format
doesn't have one.

- - - - -
622f559f by Steve Lhomme at 2023-11-10T16:28:30+00:00
subpicture: remove unused subpicture_region_TextMarkRendered

We should not transform a text region into a picture region in the same region.

- - - - -
8bac00db by Steve Lhomme at 2023-11-10T16:28:30+00:00
text_renderer: remove rendundant check on input

It's already checked by the caller via SpuRenderText().

- - - - -
f58c19a8 by Steve Lhomme at 2023-11-10T16:28:30+00:00
subpicture: don't call text renderer with no text

The text renderers and text to speech module don't produce anything if
there's no text. No need for defensive programming in each module.

- - - - -


9 changed files:

- include/vlc_filter.h
- include/vlc_subpicture.h
- modules/text_renderer/freetype/freetype.c
- modules/text_renderer/nsspeechsynthesizer.m
- modules/text_renderer/sapi.cpp
- modules/text_renderer/svg.c
- modules/text_renderer/tdummy.c
- src/video_output/vout_subpictures.c
- test/src/input/decoder/input_decoder.c


Changes:

=====================================
include/vlc_filter.h
=====================================
@@ -100,8 +100,11 @@ struct vlc_filter_operations
         /** Filter a subpicture (sub filter) */
         subpicture_t *(*filter_sub)(filter_t *, subpicture_t *);
 
-        /** Render text (text renderer) */
-        int (*render)(filter_t *, subpicture_region_t *,
+        /** Render text (text renderer)
+         *
+         * \return a picture-based region or NULL
+         */
+        subpicture_region_t * (*render)(filter_t *,
                       const subpicture_region_t *, const vlc_fourcc_t *);
     };
 


=====================================
include/vlc_subpicture.h
=====================================
@@ -178,12 +178,6 @@ VLC_API subpicture_region_t *subpicture_region_Copy( subpicture_region_t *p_regi
 #define subpicture_region_IsText(r)  \
     (((r)->text_flags & VLC_SUBPIC_TEXT_FLAG_IS_TEXT) != 0)
 
-/**
- * Marks a text-based region as rendered into the p_picture.
- */
-#define subpicture_region_TextMarkRendered(r)  \
-    ((r)->text_flags &= ~VLC_SUBPIC_TEXT_FLAG_IS_TEXT)
-
 /**
  *
  */


=====================================
modules/text_renderer/freetype/freetype.c
=====================================
@@ -342,8 +342,7 @@ error:
  *****************************************************************************
  * This function merges the previously rendered freetype glyphs into a picture
  *****************************************************************************/
-static int RenderYUVP( const subpicture_region_t *p_region_in,
-                       subpicture_region_t *p_region,
+static subpicture_region_t *RenderYUVP( const subpicture_region_t *p_region_in,
                        const line_desc_t *p_line,
                        const FT_BBox *p_regionbbox,
                        const FT_BBox *p_bbox )
@@ -370,17 +369,12 @@ static int RenderYUVP( const subpicture_region_t *p_region_in,
     fmt.space     = p_region_in->fmt.space;
     fmt.mastering = p_region_in->fmt.mastering;
 
-    assert( !p_region->p_picture );
-    p_region->p_picture = picture_NewFromFormat( &fmt );
-    if( !p_region->p_picture )
-        return VLC_EGENERIC;
-    fmt.p_palette = p_region_in->fmt.p_palette ? p_region_in->fmt.p_palette : malloc(sizeof(*fmt.p_palette));
+    subpicture_region_t *p_region = subpicture_region_New(&fmt);
+    if (unlikely(p_region == NULL))
+        return NULL;
 
-    const unsigned regionnum = p_region_in->fmt.i_sar_num;
-    const unsigned regionden = p_region_in->fmt.i_sar_den;
-    p_region->fmt = fmt;
-    p_region->fmt.i_sar_num = regionnum;
-    p_region->fmt.i_sar_den = regionden;
+    p_region->fmt.i_sar_num = p_region_in->fmt.i_sar_num;
+    p_region->fmt.i_sar_den = p_region_in->fmt.i_sar_den;
 
     /* Calculate text color components
      * Only use the first color */
@@ -458,7 +452,7 @@ static int RenderYUVP( const subpicture_region_t *p_region_in,
         memset( p_top, 0, fmt.i_width );
     }
 
-    return VLC_SUCCESS;
+    return p_region;
 }
 
 /*****************************************************************************
@@ -636,9 +630,8 @@ static void RenderCharAXYZ( filter_t *p_filter,
     }
 }
 
-static inline int RenderAXYZ( filter_t *p_filter,
+static inline subpicture_region_t *RenderAXYZ( filter_t *p_filter,
                               const subpicture_region_t *p_region_in,
-                              subpicture_region_t *p_region,
                               const line_desc_t *p_line_head,
                               const FT_BBox *p_regionbbox,
                               const FT_BBox *p_paddedtextbbox,
@@ -661,15 +654,14 @@ static inline int RenderAXYZ( filter_t *p_filter,
     fmt.space     = p_region_in->fmt.space;
     fmt.mastering = p_region_in->fmt.mastering;
 
-    picture_t *p_picture = p_region->p_picture = picture_NewFromFormat( &fmt );
-    if( !p_region->p_picture )
-        return VLC_EGENERIC;
+    subpicture_region_t *p_region = subpicture_region_New(&fmt);
+    if (unlikely(p_region == NULL))
+        return NULL;
+
+    picture_t *p_picture = p_region->p_picture;
 
-    const unsigned regionnum = p_region_in->fmt.i_sar_num;
-    const unsigned regionden = p_region_in->fmt.i_sar_den;
-    p_region->fmt = fmt;
-    p_region->fmt.i_sar_num = regionnum;
-    p_region->fmt.i_sar_den = regionden;
+    p_region->fmt.i_sar_num = p_region_in->fmt.i_sar_num;
+    p_region->fmt.i_sar_den = p_region_in->fmt.i_sar_den;
 
     /* Initialize the picture background */
     const text_style_t *p_style = p_sys->p_default_style;
@@ -708,7 +700,7 @@ static inline int RenderAXYZ( filter_t *p_filter,
         }
     }
 
-    return VLC_SUCCESS;
+    return p_region;
 }
 
 static void UpdateDefaultLiveStyles( filter_t *p_filter )
@@ -975,14 +967,12 @@ static size_t SegmentsToTextAndStyles( filter_t *p_filter, const text_segment_t
  * needed glyphs into memory. It is used as pf_add_string callback in
  * the vout method by this module
  */
-static int Render( filter_t *p_filter, subpicture_region_t *p_region_out,
+static subpicture_region_t *Render( filter_t *p_filter,
                          const subpicture_region_t *p_region_in,
                          const vlc_fourcc_t *p_chroma_list )
 {
-    if( !p_region_in || !p_region_in->p_text )
-        return VLC_EGENERIC;
-
     filter_sys_t *p_sys = p_filter->p_sys;
+    subpicture_region_t *region = NULL;
     bool b_grid = (p_region_in->text_flags & VLC_SUBPIC_TEXT_FLAG_GRID_MODE) != 0;
     p_sys->i_scale = ( b_grid ) ? 100 : var_InheritInteger( p_filter, "sub-text-scale");
 
@@ -996,7 +986,7 @@ static int Render( filter_t *p_filter, subpicture_region_t *p_region_out,
         if( !p_sys->p_faceid )
         {
             msg_Err( p_filter, "Render(): Error loading default face" );
-            return VLC_EGENERIC;
+            return NULL;
         }
         p_sys->i_font_default_size = i_font_default_size;
     }
@@ -1010,7 +1000,7 @@ static int Render( filter_t *p_filter, subpicture_region_t *p_region_out,
     {
         free( text_block.pp_styles );
         free( text_block.p_uchars );
-        return VLC_EGENERIC;
+        return NULL;
     }
 
     /* */
@@ -1120,12 +1110,11 @@ static int Render( filter_t *p_filter, subpicture_region_t *p_region_out,
         regionbbox = paddedbbox;
     }
 
-    rv = VLC_EGENERIC;
     for( const vlc_fourcc_t *p_chroma = p_chroma_list; *p_chroma != 0; p_chroma++ )
     {
         if( *p_chroma == VLC_CODEC_YUVP )
-            rv = RenderYUVP( p_region_in, p_region_out, text_block.p_laid,
-                             &regionbbox, &bbox );
+            region = RenderYUVP( p_region_in, text_block.p_laid,
+                                &regionbbox, &bbox );
         else
         {
             const ft_drawing_functions *func;
@@ -1158,29 +1147,29 @@ static int Render( filter_t *p_filter, subpicture_region_t *p_region_out,
             else
                 continue;
 
-            rv = RenderAXYZ( p_filter, p_region_in, p_region_out, text_block.p_laid,
-                             &regionbbox, &paddedbbox, &bbox,
-                             *p_chroma,
-                             func );
+            region = RenderAXYZ( p_filter, p_region_in, text_block.p_laid,
+                                 &regionbbox, &paddedbbox, &bbox,
+                                 *p_chroma,
+                                 func );
         }
 
-        if( rv == VLC_SUCCESS )
+        if( region != NULL )
         {
-            subpicture_region_TextMarkRendered( p_region_out );
-
             /* Avoid useless pixels:
                 *        reshrink/trim Region Box to padded text one,
                 *        but update offsets to keep position and have same rendering */
 //          if( (bboxcolor & 0xFF) == 0 )
             {
-                p_region_out->i_x = (paddedbbox.xMin - regionbbox.xMin) + p_region_in->i_x;
-                p_region_out->i_y = (regionbbox.yMax - paddedbbox.yMax) + p_region_in->i_y;
+                region->i_x = (paddedbbox.xMin - regionbbox.xMin) + p_region_in->i_x;
+                region->i_y = (regionbbox.yMax - paddedbbox.yMax) + p_region_in->i_y;
             }
 //          else /* case where the bounding box is larger and visible */
 //          {
-//              p_region_out->i_x = p_region_in->i_x;
-//              p_region_out->i_y = p_region_in->i_y;
+//              region->i_x = p_region_in->i_x;
+//              region->i_y = p_region_in->i_y;
 //          }
+            region->i_alpha = p_region_in->i_alpha;
+            region->i_align = p_region_in->i_align;
             break;
         }
     }
@@ -1193,7 +1182,7 @@ done:
     if( text_block.pp_ruby )
         FreeRubyBlockArray( text_block.pp_ruby, text_block.i_count );
 
-    return rv;
+    return region;
 }
 
 static const struct vlc_filter_operations filter_ops =


=====================================
modules/text_renderer/nsspeechsynthesizer.m
=====================================
@@ -37,8 +37,7 @@
 
 static int Create (filter_t *);
 static void Destroy(filter_t *);
-static int RenderText(filter_t *,
-                      subpicture_region_t *,
+static subpicture_region_t *RenderText(filter_t *,
                       const subpicture_region_t *,
                       const vlc_fourcc_t *);
 
@@ -97,8 +96,7 @@ static NSString * languageCodeForString(NSString *string) {
     return (NSString *)CFStringTokenizerCopyBestStringLanguage((CFStringRef)string, CFRangeMake(0, [string length]));
 }
 
-static int RenderText(filter_t *p_filter,
-                      subpicture_region_t *p_region_out,
+static subpicture_region_t *RenderText(filter_t *p_filter,
                       const subpicture_region_t *p_region_in,
                       const vlc_fourcc_t *p_chroma_list)
 {
@@ -106,9 +104,6 @@ static int RenderText(filter_t *p_filter,
         filter_sys_t *p_sys = p_filter->p_sys;
         const text_segment_t *p_segment = p_region_in->p_text;
 
-        if (!p_segment)
-            return VLC_EGENERIC;
-
         for ( const text_segment_t *s = p_segment; s != NULL; s = s->p_next ) {
             if ( !s->psz_text )
                 continue;
@@ -155,6 +150,6 @@ static int RenderText(filter_t *p_filter,
             [p_sys->speechSynthesizer startSpeakingString:stringToSpeech];
         }
 
-        return VLC_SUCCESS;
+        return NULL;
     }
 }


=====================================
modules/text_renderer/sapi.cpp
=====================================
@@ -56,8 +56,7 @@ DEFINE_GUID(CLSID_SpObjectTokenCategory, 0xa910187f, 0x0c7a, 0x45ac, 0x92,0xcc,
 extern "C" {
 static int Create (filter_t *);
 static void Destroy(filter_t *);
-static int RenderText(filter_t *,
-                      subpicture_region_t *,
+static subpicture_region_t *RenderText(filter_t *,
                       const subpicture_region_t *,
                       const vlc_fourcc_t *);
 }
@@ -130,9 +129,6 @@ static int RenderTextMTA(filter_t *p_filter,
     struct filter_sapi *p_sys = static_cast<struct filter_sapi *>( p_filter->p_sys );
     const text_segment_t *p_segment = p_region_in->p_text;
 
-    if (!p_segment)
-        return VLC_EGENERIC;
-
     for (const text_segment_t *s = p_segment; s != NULL; s = s->p_next ) {
         if (!s->psz_text)
             continue;
@@ -213,8 +209,7 @@ error:
     return -ENOENT;
 }
 
-static int RenderText(filter_t *p_filter,
-        subpicture_region_t *,
+static subpicture_region_t *RenderText(filter_t *p_filter,
         const subpicture_region_t *region_in,
         const vlc_fourcc_t *)
 {
@@ -223,7 +218,7 @@ static int RenderText(filter_t *p_filter,
     sys->cmd.render_text.region = region_in;
     sys->cmd_available.post();
     sys->cmd_ready.wait();
-    return VLC_EGENERIC; /* We don't generate output region. */
+    return NULL; /* We don't generate output region. */
 }
 
 static const struct vlc_filter_operations filter_ops = []{


=====================================
modules/text_renderer/svg.c
=====================================
@@ -49,7 +49,7 @@
  *****************************************************************************/
 static int  Create    ( filter_t * );
 static void Destroy   ( filter_t * );
-static int  RenderText( filter_t *p_filter, subpicture_region_t *p_region_out,
+static subpicture_region_t *RenderText( filter_t *p_filter,
                         const subpicture_region_t *p_region_in,
                         const vlc_fourcc_t * );
 
@@ -328,25 +328,18 @@ static char * SegmentsToSVG( text_segment_t *p_segment, int i_height, int *pi_to
     return psz_result;
 }
 
-static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out,
+static subpicture_region_t *RenderText( filter_t *p_filter,
                        const subpicture_region_t *p_region_in,
                        const vlc_fourcc_t *p_chroma_list )
 {
-    /* Sanity check */
-    if( !p_region_in || !p_region_out || !p_region_in->p_text )
-        return VLC_EGENERIC;
-
     for( size_t i=0; p_chroma_list[i]; i++ )
     {
         if( p_chroma_list[i] == VLC_CODEC_BGRA )
             break;
         if( p_chroma_list[i] == 0 )
-            return VLC_EGENERIC;
+            return NULL;
     }
 
-    p_region_out->i_x = p_region_in->i_x;
-    p_region_out->i_y = p_region_in->i_y;
-
     unsigned i_width = p_filter->fmt_out.video.i_visible_width;
     if( (unsigned) p_region_in->i_x <= i_width )
         i_width -= p_region_in->i_x;
@@ -356,7 +349,7 @@ static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out,
         i_height -= p_region_in->i_y;
 
     if( i_height == 0 || i_width == 0 )
-        return VLC_EGENERIC;
+        return NULL;
 
     char *psz_svg;
     /* Check if the data is SVG or pure text. In the latter case,
@@ -379,19 +372,23 @@ static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out,
     }
 
     if( !psz_svg )
-        return VLC_EGENERIC;
+        return NULL;
 
     picture_t *p_picture = svg_RenderPicture( p_filter, psz_svg );
 
     free( psz_svg );
 
-    if (p_picture)
-    {
-        p_region_out->p_picture = p_picture;
-        video_format_Clean( &p_region_out->fmt );
-        video_format_Copy( &p_region_out->fmt, &p_picture->format );
-        subpicture_region_TextMarkRendered(p_region_out);
-        return VLC_SUCCESS;
-    }
-    return VLC_EGENERIC;
+    if (p_picture == NULL)
+        return NULL;
+
+    subpicture_region_t *p_region_out = subpicture_region_ForPicture(&p_picture->format, p_picture);
+    picture_Release(p_picture);
+    if (unlikely(p_region_out == NULL))
+        return NULL;
+    p_region_out->i_x     = p_region_in->i_x;
+    p_region_out->i_y     = p_region_in->i_y;
+    p_region_out->i_alpha = p_region_in->i_alpha;
+    p_region_out->i_align = p_region_in->i_align;
+
+    return p_region_out;
 }


=====================================
modules/text_renderer/tdummy.c
=====================================
@@ -37,13 +37,13 @@ vlc_module_begin ()
 vlc_module_end ()
 
 
-static int RenderText( filter_t *p_filter, subpicture_region_t *p_region_out,
+static subpicture_region_t *RenderText( filter_t *p_filter,
                        const subpicture_region_t *p_region_in,
                        const vlc_fourcc_t *p_chroma_list )
 {
-    VLC_UNUSED(p_filter); VLC_UNUSED(p_region_out); VLC_UNUSED(p_region_in);
+    VLC_UNUSED(p_filter); VLC_UNUSED(p_region_in);
     VLC_UNUSED(p_chroma_list);
-    return VLC_EGENERIC;
+    return NULL;
 }
 
 static const struct vlc_filter_operations filter_ops = {


=====================================
src/video_output/vout_subpictures.c
=====================================
@@ -313,7 +313,7 @@ static filter_t *SpuRenderCreateAndLoadScale(vlc_object_t *object,
     return scale;
 }
 
-static int SpuRenderText(spu_t *spu,
+static subpicture_region_t *SpuRenderText(spu_t *spu,
                           subpicture_region_t *region,
                           unsigned i_original_width,
                           unsigned i_original_height,
@@ -321,13 +321,15 @@ static int SpuRenderText(spu_t *spu,
 {
     spu_private_t *sys = spu->p;
     assert(subpicture_region_IsText( region ));
+    if ( region->p_text == NULL )
+        return NULL;
 
     vlc_mutex_lock(&sys->textlock);
     filter_t *text = sys->text;
     if(unlikely(text == NULL))
     {
         vlc_mutex_unlock(&sys->textlock);
-        return VLC_EGENERIC;
+        return NULL;
     }
 
     // assume rendered text is in sRGB if nothing is set
@@ -347,10 +349,11 @@ static int SpuRenderText(spu_t *spu,
     text->fmt_out.video.i_height =
     text->fmt_out.video.i_visible_height = i_original_height;
 
-    int i_ret = text->ops->render(text, region, region, chroma_list);
+    subpicture_region_t *rendered_region = text->ops->render(text, region, chroma_list);
+    assert(rendered_region == NULL || !subpicture_region_IsText(rendered_region));
 
     vlc_mutex_unlock(&sys->textlock);
-    return i_ret;
+    return rendered_region;
 }
 
 /**
@@ -808,13 +811,15 @@ static subpicture_region_t *SpuRenderRegion(spu_t *spu,
     /* Render text region */
     if (subpicture_region_IsText( region ))
     {
-        if(SpuRenderText(spu, region,
+        subpicture_region_t *rendered_text =
+            SpuRenderText(spu, region,
                       i_original_width, i_original_height,
-                      chroma_list) != VLC_SUCCESS)
-            return NULL;
-        if(subpicture_region_IsText( region ))
+                      chroma_list);
+        if ( rendered_text  == NULL)
             // not a rendering error for Text-To-Speech
             return NULL;
+        // FIXME notify the caller it is allocated
+        region = rendered_text;
     }
 
     video_format_AdjustColorSpace(&region->fmt);
@@ -1530,9 +1535,16 @@ static void spu_PrerenderText(spu_t *spu, subpicture_t *p_subpic,
     {
         if(!subpicture_region_IsText( region ))
             continue;
-        SpuRenderText(spu, region,
-                      i_original_picture_width, i_original_picture_height,
-                      chroma_list);
+        subpicture_region_t *rendered_text =
+            SpuRenderText(spu, region,
+                        i_original_picture_width, i_original_picture_height,
+                        chroma_list);
+        if (rendered_text == NULL)
+            vlc_spu_regions_remove(&p_subpic->regions, region);
+        else
+            // replace the text region with the rendered region
+            vlc_list_replace(&region->node, &rendered_text->node);
+        subpicture_region_Delete(region);
     }
 }
 


=====================================
test/src/input/decoder/input_decoder.c
=====================================
@@ -255,15 +255,15 @@ static int OpenWindow(vlc_window_t *wnd)
     return VLC_SUCCESS;
 }
 
-static int TextRendererRender(filter_t *filter, subpicture_region_t *region_out,
+static subpicture_region_t *TextRendererRender(filter_t *filter,
                               const subpicture_region_t *region_in,
                               const vlc_fourcc_t *chroma_list)
 {
-    (void) region_out; (void) chroma_list;
+    (void) chroma_list;
     struct input_decoder_scenario *scenario = &input_decoder_scenarios[current_scenario];
     if (scenario->text_renderer_render != NULL)
         scenario->text_renderer_render(filter, region_in);
-    return VLC_EGENERIC;
+    return NULL;
 }
 
 static int OpenTextRenderer(filter_t *filter)



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/dd58d1c0acb1eaca83ae6636de4e731cbea4b022...f58c19a8b4cfb0d0dc3849858f673e9229c2e4e5

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/dd58d1c0acb1eaca83ae6636de4e731cbea4b022...f58c19a8b4cfb0d0dc3849858f673e9229c2e4e5
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list