[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,
- ®ionbbox, &bbox );
+ region = RenderYUVP( p_region_in, text_block.p_laid,
+ ®ionbbox, &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,
- ®ionbbox, &paddedbbox, &bbox,
- *p_chroma,
- func );
+ region = RenderAXYZ( p_filter, p_region_in, text_block.p_laid,
+ ®ionbbox, &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(®ion->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(®ion->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