*****************************************************************************/
static subpicture_t *DecodeBlock( decoder_t *, block_t ** );
static void DestroySubpicture( subpicture_t * );
-static void PreRender( video_format_t *, spu_t *, subpicture_t * );
-static void UpdateRegions( video_format_t *, spu_t *,
- subpicture_t *, mtime_t );
+static void PreRender( spu_t *, subpicture_t *, const video_format_t * );
+static void UpdateRegions( spu_t *,
+ subpicture_t *, const video_format_t *, mtime_t );
/* Yes libass sux with threads */
typedef struct
ass_renderer_t *p_renderer;
video_format_t fmt;
} ass_handle_t;
-static ass_handle_t *AssHandleYield( decoder_t *p_dec );
+static ass_handle_t *AssHandleHold( decoder_t *p_dec );
static void AssHandleRelease( ass_handle_t * );
/* */
subpicture_t *p_spu_final;
};
static void DecSysRelease( decoder_sys_t *p_sys );
-static void DecSysYield( decoder_sys_t *p_sys );
+static void DecSysHold( decoder_sys_t *p_sys );
struct subpicture_sys_t
{
return VLC_ENOMEM;
/* */
- vlc_mutex_init( &p_sys->lock );
- p_sys->i_refcount = 1;
-
- p_sys->p_ass = AssHandleYield( p_dec );
-
- /* load attachments */
- input_attachment_t **pp_attachments;
- int i_attachments;
-
- if( decoder_GetInputAttachments( p_dec, &pp_attachments, &i_attachments ))
- {
- i_attachments = 0;
- pp_attachments = NULL;
- }
- for( int k = 0; k < i_attachments; k++ )
+ p_sys->p_ass = AssHandleHold( p_dec );
+ if( !p_sys->p_ass )
{
- input_attachment_t *p_attach = pp_attachments[k];
-
- if( !strcasecmp( p_attach->psz_mime, "application/x-truetype-font" ) )
- {
- msg_Dbg( p_dec, "adding embedded font %s\n", p_attach->psz_name );
-
- vlc_mutex_lock( p_sys->p_ass->p_lock );
- ass_add_font( p_sys->p_ass->p_library, p_attach->psz_name, p_attach->p_data, p_attach->i_data );
- vlc_mutex_unlock( p_sys->p_ass->p_lock );
- }
- vlc_input_attachment_Delete( p_attach );
+ free( p_sys );
+ return VLC_EGENERIC;
}
- free( pp_attachments );
+ vlc_mutex_init( &p_sys->lock );
+ p_sys->i_refcount = 1;
/* Add a track */
vlc_mutex_lock( p_sys->p_ass->p_lock );
p_sys->p_track = p_track = ass_new_track( p_sys->p_ass->p_library );
+ if( !p_track )
+ {
+ vlc_mutex_unlock( p_sys->p_ass->p_lock );
+ DecSysRelease( p_sys );
+ return VLC_EGENERIC;
+ }
ass_process_codec_private( p_track, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
vlc_mutex_unlock( p_sys->p_ass->p_lock );
DecSysRelease( p_dec->p_sys );
}
-static void DecSysYield( decoder_sys_t *p_sys )
+static void DecSysHold( decoder_sys_t *p_sys )
{
vlc_mutex_lock( &p_sys->lock );
p_sys->i_refcount++;
vlc_mutex_destroy( &p_sys->lock );
vlc_mutex_lock( p_sys->p_ass->p_lock );
- ass_free_track( p_sys->p_track );
+ if( p_sys->p_track )
+ ass_free_track( p_sys->p_track );
vlc_mutex_unlock( p_sys->p_ass->p_lock );
AssHandleRelease( p_sys->p_ass );
subpicture_t *p_spu = NULL;
block_t *p_block;
- //msg_Dbg( p_dec, "DecodeBlock %p", (void *)pp_block);
if( !pp_block || *pp_block == NULL )
return NULL;
p_block = *pp_block;
+ if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
+ {
+ msg_Dbg( p_dec, "Resetting libass track after time discontinuity" );
+ /* We need to reset our tracks for the time discontinuity to be
+ * handled */
+ vlc_mutex_lock( p_sys->p_ass->p_lock );
+ if( p_sys->p_track )
+ ass_free_track( p_sys->p_track );
+
+ p_sys->p_track = ass_new_track( p_sys->p_ass->p_library );
+ if( p_sys->p_track )
+ ass_process_codec_private( p_sys->p_track,
+ p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
+ vlc_mutex_unlock( p_sys->p_ass->p_lock );
+
+ block_Release( p_block );
+ return NULL;
+ }
if( p_block->i_rate != 0 )
p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT;
*pp_block = NULL;
memcpy( p_spu->p_sys->p_subs_data, p_block->p_buffer,
p_block->i_buffer );
- p_spu->i_x = 0;
- p_spu->i_y = 0;
p_spu->i_start = p_block->i_pts;
p_spu->i_stop = p_block->i_pts + p_block->i_length;
p_spu->b_ephemer = true;
p_spu->b_absolute = true;
- p_spu->b_pausable = true; /* ? */
vlc_mutex_lock( p_sys->p_ass->p_lock );
- ass_process_chunk( p_sys->p_track, p_spu->p_sys->p_subs_data, p_spu->p_sys->i_subs_len,
- p_spu->i_start / 1000, (p_spu->i_stop-p_spu->i_start) / 1000 );
+ if( p_sys->p_track )
+ {
+ ass_process_chunk( p_sys->p_track, p_spu->p_sys->p_subs_data, p_spu->p_sys->i_subs_len,
+ p_spu->i_start / 1000, (p_spu->i_stop-p_spu->i_start) / 1000 );
+ }
vlc_mutex_unlock( p_sys->p_ass->p_lock );
p_spu->pf_pre_render = PreRender;
p_spu->pf_destroy = DestroySubpicture;
p_spu->p_sys->p_dec_sys = p_sys;
- DecSysYield( p_sys );
+ DecSysHold( p_sys );
block_Release( p_block );
free( p_subpic->p_sys );
}
-static void PreRender( video_format_t *p_fmt, spu_t *p_spu,
- subpicture_t *p_subpic )
+static void PreRender( spu_t *p_spu, subpicture_t *p_subpic,
+ const video_format_t *p_fmt )
{
decoder_sys_t *p_dec_sys = p_subpic->p_sys->p_dec_sys;
VLC_UNUSED(p_spu);
}
-static void UpdateRegions( video_format_t *p_fmt, spu_t *p_spu,
- subpicture_t *p_subpic, mtime_t i_ts )
+static void UpdateRegions( spu_t *p_spu, subpicture_t *p_subpic,
+ const video_format_t *p_fmt, mtime_t i_ts )
{
decoder_sys_t *p_sys = p_subpic->p_sys->p_dec_sys;
ass_handle_t *p_ass = p_sys->p_ass;
fmt.i_height = fmt.i_visible_height;
fmt.i_bits_per_pixel = 0;
fmt.i_x_offset = fmt.i_y_offset = 0;
- fmt.i_sar_num = 1;
- fmt.i_sar_den = 1;
b_fmt_changed = memcmp( &fmt, &p_ass->fmt, sizeof(fmt) ) != 0;
if( b_fmt_changed )
fmt_region.i_height =
fmt_region.i_visible_height = region[i].y1 - region[i].y0;
- pp_region[i] = r = p_subpic->pf_create_region( VLC_OBJECT(p_spu), &fmt_region );
+ pp_region[i] = r = subpicture_region_New( &fmt_region );
if( !r )
break;
r->i_x = region[i].x0;
static void RegionDraw( subpicture_region_t *p_region, ass_image_t *p_img )
{
- const plane_t *p = &p_region->picture.p[0];
+ const plane_t *p = &p_region->p_picture->p[0];
const int i_x = p_region->i_x;
const int i_y = p_region->i_y;
const int i_width = p_region->fmt.i_width;
const int an = (255 - a) * alpha / 255;
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)];
-#if 0
- p_rgba[0] = b;
- p_rgba[1] = g;
- p_rgba[2] = r;
- p_rgba[3] = an;
-#else
- // FIXME it is not right
- p_rgba[0] = ( p_rgba[0] * (255-an) + b * an ) / 255;
+
+ /* Native endianness, but RGBA ordering */
+ p_rgba[0] = ( p_rgba[0] * (255-an) + r * an ) / 255;
p_rgba[1] = ( p_rgba[1] * (255-an) + g * an ) / 255;
- p_rgba[2] = ( p_rgba[2] * (255-an) + r * an ) / 255;
+ p_rgba[2] = ( p_rgba[2] * (255-an) + b * an ) / 255;
p_rgba[3] = 255 - ( 255 - p_rgba[3] ) * ( 255 - an ) / 255;
-#endif
}
}
}
static void SubpictureReleaseRegions( spu_t *p_spu, subpicture_t *p_subpic )
{
- while( p_subpic->p_region )
- {
- subpicture_region_t *p_region = p_subpic->p_region;
- p_subpic->p_region = p_region->p_next;
- spu_DestroyRegion( p_spu, p_region );
- }
+ subpicture_region_ChainDelete( p_subpic->p_region );
p_subpic->p_region = NULL;
}
/* */
-static ass_handle_t *AssHandleYield( decoder_t *p_dec )
+static ass_handle_t *AssHandleHold( decoder_t *p_dec )
{
vlc_mutex_t *p_lock = var_AcquireMutex( "libass" );
if( !p_lock )
if( !p_library )
goto error;
- ass_set_fonts_dir( p_library, "/usr/share/fonts" ); // FIXME
+ /* load attachments */
+ input_attachment_t **pp_attachments;
+ int i_attachments;
+
+ if( decoder_GetInputAttachments( p_dec, &pp_attachments, &i_attachments ))
+ {
+ i_attachments = 0;
+ pp_attachments = NULL;
+ }
+ for( int k = 0; k < i_attachments; k++ )
+ {
+ input_attachment_t *p_attach = pp_attachments[k];
+
+ if( !strcasecmp( p_attach->psz_mime, "application/x-truetype-font" ) )
+ {
+ msg_Dbg( p_dec, "adding embedded font %s", p_attach->psz_name );
+
+ ass_add_font( p_ass->p_library, p_attach->psz_name, p_attach->p_data, p_attach->i_data );
+ }
+ vlc_input_attachment_Delete( p_attach );
+ }
+ free( pp_attachments );
+
+ char *psz_font_dir = config_GetCacheDir();
+ if( !psz_font_dir )
+ goto error;
+ ass_set_fonts_dir( p_library, psz_font_dir );
+ free( psz_font_dir );
+
ass_set_extract_fonts( p_library, true );
ass_set_style_overrides( p_library, NULL );
ass_set_font_scale( p_renderer, 1.0 );
ass_set_line_spacing( p_renderer, 0.0 );
- const char *psz_font = "";//"/usr/src/videolan/vlc-libass.git/share/skins2/fonts/FreeSans.ttf"; // FIXME
- const char *psz_family = "";//"Arial"; // FIXME
+ const char *psz_font = NULL; /* We don't ship a default font with VLC */
+ const char *psz_family = "Arial"; /* Use Arial if we can't find anything more suitable */
#ifdef HAVE_FONTCONFIG
ass_set_fonts( p_renderer, psz_font, psz_family ); // setup default font/family
#else