[vlc-commits] [Git][videolan/vlc][master] 2 commits: codec: libass: don't create spu for each split command
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Thu Jul 8 08:41:11 UTC 2021
Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC
Commits:
ffb4a94e by Francois Cartegnie at 2021-07-08T07:58:14+00:00
codec: libass: don't create spu for each split command
- - - - -
296e18b1 by Francois Cartegnie at 2021-07-08T07:58:14+00:00
codec: libass: speed up C blending, as for freetype
- - - - -
1 changed file:
- modules/codec/libass.c
Changes:
=====================================
modules/codec/libass.c
=====================================
@@ -76,6 +76,7 @@ static void Flush( decoder_t * );
/* */
typedef struct
{
+ vlc_tick_t i_last_pts;
vlc_tick_t i_max_stop;
/* The following fields of decoder_sys_t are shared between decoder and spu units */
@@ -107,8 +108,6 @@ static void SubpictureDestroy( subpicture_t * );
typedef struct
{
decoder_sys_t *p_dec_sys;
- void *p_subs_data;
- int i_subs_len;
vlc_tick_t i_pts;
ASS_Image *p_img;
@@ -148,7 +147,8 @@ static int Create( vlc_object_t *p_this )
/* */
vlc_mutex_init( &p_sys->lock );
p_sys->i_refcount = 1;
- memset( &p_sys->fmt, 0, sizeof(p_sys->fmt) );
+ video_format_Init( &p_sys->fmt, 0 );
+ p_sys->i_last_pts = VLC_TICK_INVALID;
p_sys->i_max_stop = VLC_TICK_INVALID;
p_sys->p_library = NULL;
p_sys->p_renderer = NULL;
@@ -332,6 +332,7 @@ static void Flush( decoder_t *p_dec )
decoder_sys_t *p_sys = p_dec->p_sys;
p_sys->i_max_stop = VLC_TICK_INVALID;
+ p_sys->i_last_pts = VLC_TICK_INVALID;
}
/****************************************************************************
@@ -359,62 +360,59 @@ static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
return VLCDEC_SUCCESS;
}
- libass_spu_updater_sys_t *p_spu_sys = malloc( sizeof(*p_spu_sys) );
- if( !p_spu_sys )
+ if( p_block->i_pts != p_sys->i_last_pts )
{
- block_Release( p_block );
- return VLCDEC_SUCCESS;
- }
+ libass_spu_updater_sys_t *p_spu_sys = malloc( sizeof(*p_spu_sys) );
+ if( !p_spu_sys )
+ {
+ block_Release( p_block );
+ return VLCDEC_SUCCESS;
+ }
- subpicture_updater_t updater = {
- .pf_validate = SubpictureValidate,
- .pf_update = SubpictureUpdate,
- .pf_destroy = SubpictureDestroy,
- .p_sys = p_spu_sys,
- };
- p_spu = decoder_NewSubpicture( p_dec, &updater );
- if( !p_spu )
- {
- msg_Warn( p_dec, "can't get spu buffer" );
- free( p_spu_sys );
- block_Release( p_block );
- return VLCDEC_SUCCESS;
- }
+ subpicture_updater_t updater = {
+ .pf_validate = SubpictureValidate,
+ .pf_update = SubpictureUpdate,
+ .pf_destroy = SubpictureDestroy,
+ .p_sys = p_spu_sys,
+ };
- p_spu_sys->p_img = NULL;
- p_spu_sys->p_dec_sys = p_sys;
- p_spu_sys->i_subs_len = p_block->i_buffer;
- p_spu_sys->p_subs_data = malloc( p_block->i_buffer );
- p_spu_sys->i_pts = p_block->i_pts;
- if( !p_spu_sys->p_subs_data )
- {
- subpicture_Delete( p_spu );
- block_Release( p_block );
- return VLCDEC_SUCCESS;
- }
- memcpy( p_spu_sys->p_subs_data, p_block->p_buffer,
- p_block->i_buffer );
+ p_spu = decoder_NewSubpicture( p_dec, &updater );
+ if( !p_spu )
+ {
+ msg_Warn( p_dec, "can't get spu buffer" );
+ free( p_spu_sys );
+ block_Release( p_block );
+ return VLCDEC_SUCCESS;
+ }
- p_spu->i_start = p_block->i_pts;
- p_spu->i_stop = __MAX( p_sys->i_max_stop, p_block->i_pts + p_block->i_length );
- p_spu->b_ephemer = true;
- p_spu->b_absolute = true;
+ p_spu_sys->p_img = NULL;
+ p_spu_sys->p_dec_sys = p_sys;
+ p_spu_sys->i_pts = p_block->i_pts;
+ p_spu->i_start = p_block->i_pts;
+ p_spu->i_stop = __MAX( p_sys->i_max_stop, p_block->i_pts + p_block->i_length );
+ p_spu->b_ephemer = true;
+ p_spu->b_absolute = true;
- p_sys->i_max_stop = p_spu->i_stop;
+ p_sys->i_max_stop = p_spu->i_stop;
+
+ DecSysHold( p_sys ); /* Keep a reference for the returned subpicture */
+ }
+
+ p_sys->i_last_pts = p_block->i_pts;
vlc_mutex_lock( &p_sys->lock );
if( p_sys->p_track )
{
- ass_process_chunk( p_sys->p_track, p_spu_sys->p_subs_data, p_spu_sys->i_subs_len,
+ ass_process_chunk( p_sys->p_track,(void *) p_block->p_buffer, p_block->i_buffer,
MS_FROM_VLC_TICK( p_block->i_pts ), MS_FROM_VLC_TICK( p_block->i_length ) );
}
vlc_mutex_unlock( &p_sys->lock );
- DecSysHold( p_sys ); /* Keep a reference for the returned subpicture */
-
block_Release( p_block );
- decoder_QueueSub( p_dec, p_spu );
+ if( p_spu )
+ decoder_QueueSub( p_dec, p_spu );
+
return VLCDEC_SUCCESS;
}
@@ -533,7 +531,6 @@ static void SubpictureDestroy( subpicture_t *p_subpic )
libass_spu_updater_sys_t *p_spusys = p_subpic->updater.p_sys;
DecSysRelease( p_spusys->p_dec_sys );
- free( p_spusys->p_subs_data );
free( p_spusys );
}
@@ -699,49 +696,65 @@ static void RegionDraw( subpicture_region_t *p_region, ASS_Image *p_img )
const int i_width = p_region->fmt.i_width;
const int i_height = p_region->fmt.i_height;
- memset( p->p_pixels, 0x00, p->i_pitch * p->i_lines );
+ memset( p->p_pixels, 0x00, p->i_pitch * p->i_visible_lines );
for( ; p_img != NULL; p_img = p_img->next )
{
- if( p_img->dst_x < i_x || p_img->dst_x + p_img->w > i_x + i_width ||
- p_img->dst_y < i_y || p_img->dst_y + p_img->h > i_y + i_height )
+ int i_dst_x = p_img->dst_x - i_x;
+ int i_dst_y = p_img->dst_y - i_y;
+ if( i_dst_x < 0 || i_dst_x + p_img->w > i_width ||
+ i_dst_y < 0 || i_dst_y + p_img->h > i_height )
+ continue;
+
+ /* /!\ Bogus alpha channel is inverted */
+ const unsigned a = (~p_img->color )&0xff;
+ if( a == 0 )
continue;
const unsigned r = (p_img->color >> 24)&0xff;
const unsigned g = (p_img->color >> 16)&0xff;
const unsigned b = (p_img->color >> 8)&0xff;
- const unsigned a = (p_img->color )&0xff;
- int x, y;
- for( y = 0; y < p_img->h; y++ )
- {
- for( x = 0; x < p_img->w; x++ )
- {
- const unsigned alpha = p_img->bitmap[y*p_img->stride+x];
- const unsigned an = (255 - a) * alpha / 255;
+ const uint8_t *srcrow = p_img->bitmap;
+ int i_pitch_src = p_img->stride;
+ int i_pitch_dst = p->i_pitch;
+ uint8_t *dstrow = &p->p_pixels[i_dst_y * i_pitch_dst + 4 * i_dst_x];
- uint8_t *p_rgba = &p->p_pixels[(y+p_img->dst_y-i_y) * p->i_pitch + 4 * (x+p_img->dst_x-i_x)];
- const unsigned ao = p_rgba[3];
+ for( int y = 0; y < p_img->h; y++ )
+ {
+ const uint8_t *src = srcrow;
+ uint8_t *dst = dstrow;
- /* Native endianness, but RGBA ordering */
- if( ao == 0 )
- {
- /* Optimized but the else{} will produce the same result */
- p_rgba[0] = r;
- p_rgba[1] = g;
- p_rgba[2] = b;
- p_rgba[3] = an;
- }
- else
+ for( int x = 0; x < p_img->w; x++ )
+ {
+ unsigned opacity = *src++; /* 1 Bpp channel */
+ if( opacity != 0 ) /* we need to blend only non transparent content */
{
- p_rgba[3] = 255 - ( 255 - p_rgba[3] ) * ( 255 - an ) / 255;
- if( p_rgba[3] != 0 )
+ unsigned i_an = a * opacity / 255U;
+ unsigned i_ao = dst[3];
+ if( i_ao == 0 )
+ {
+ dst[0] = r;
+ dst[1] = g;
+ dst[2] = b;
+ dst[3] = i_an;
+ }
+ else
{
- p_rgba[0] = ( p_rgba[0] * ao * (255-an) / 255 + r * an ) / p_rgba[3];
- p_rgba[1] = ( p_rgba[1] * ao * (255-an) / 255 + g * an ) / p_rgba[3];
- p_rgba[2] = ( p_rgba[2] * ao * (255-an) / 255 + b * an ) / p_rgba[3];
+ unsigned i_ani = 255 - i_an;
+ dst[3] = 255 - (255 - i_ao) * i_ani / 255;
+ if( dst[3] != 0 )
+ {
+ unsigned i_aoni = i_ao * i_ani / 255;
+ dst[0] = ( dst[0] * i_aoni + r * i_an ) / dst[3];
+ dst[1] = ( dst[1] * i_aoni + g * i_an ) / dst[3];
+ dst[2] = ( dst[2] * i_aoni + b * i_an ) / dst[3];
+ }
}
}
+ dst += 4;
}
+ srcrow += i_pitch_src;
+ dstrow += i_pitch_dst;
}
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/72d7150e61cb4ebcef586d110259b28b968943f6...296e18b19c189a4e7409e7a34f897bb21dfdc1fa
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/72d7150e61cb4ebcef586d110259b28b968943f6...296e18b19c189a4e7409e7a34f897bb21dfdc1fa
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list