Dynamic subtitles are used by ssa and kate.
This commit breaks the API for 2 functions used by the transcode module.
*
* The returned list can only be used by spu_RenderSubpictures.
*/
*
* The returned list can only be used by spu_RenderSubpictures.
*/
-VLC_EXPORT( subpicture_t *, spu_SortSubpictures, ( spu_t *, mtime_t display_date, bool b_paused, bool b_subtitle_only ) );
+VLC_EXPORT( subpicture_t *, spu_SortSubpictures, ( spu_t *, mtime_t render_date, bool b_subtitle_only ) );
/**
* This function renders a list of subpicture_t on the provided picture.
/**
* This function renders a list of subpicture_t on the provided picture.
* \param p_fmt_dst is the format of the destination picture.
* \param p_fmt_src is the format of the original(source) video.
*/
* \param p_fmt_dst is the format of the destination picture.
* \param p_fmt_src is the format of the original(source) video.
*/
-VLC_EXPORT( void, spu_RenderSubpictures, ( spu_t *, picture_t *, const video_format_t *p_fmt_dst, subpicture_t *p_list, const video_format_t *p_fmt_src, bool b_paused ) );
+VLC_EXPORT( void, spu_RenderSubpictures, ( spu_t *, picture_t *, const video_format_t *p_fmt_dst, subpicture_t *p_list, const video_format_t *p_fmt_src, mtime_t render_date ) );
/* Check if we have a subpicture to overlay */
if( p_sys->p_spu )
{
/* Check if we have a subpicture to overlay */
if( p_sys->p_spu )
{
- p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date,
- false /* Fixme: check if stream is paused */, false );
+ p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date, false );
/* TODO: get another pic */
}
/* TODO: get another pic */
}
fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
fmt.i_sar_den = VOUT_ASPECT_FACTOR;
fmt.i_sar_num = fmt.i_aspect * fmt.i_height / fmt.i_width;
fmt.i_sar_den = VOUT_ASPECT_FACTOR;
+ /* FIXME the mdate() seems highly suspicious */
spu_RenderSubpictures( p_sys->p_spu, p_pic, &fmt,
spu_RenderSubpictures( p_sys->p_spu, p_pic, &fmt,
- p_subpic, &id->p_decoder->fmt_out.video, false );
+ p_subpic, &id->p_decoder->fmt_out.video, mdate() );
}
/* Run user specified filter chain */
}
/* Run user specified filter chain */
/* Check if we have a subpicture to send */
if( p_sys->p_spu && in->i_dts > 0)
{
/* Check if we have a subpicture to send */
if( p_sys->p_spu && in->i_dts > 0)
{
- p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false, false );
+ p_subpic = spu_SortSubpictures( p_sys->p_spu, in->i_dts, false );
/*
* Check for subpictures to display
*/
/*
* Check for subpictures to display
*/
+ mtime_t spu_render_time;
+ if( p_vout->p->b_paused )
+ spu_render_time = p_vout->p->i_pause_date;
+ else
+ spu_render_time = p_picture ? p_picture->date : mdate();
+
subpicture_t *p_subpic = NULL;
subpicture_t *p_subpic = NULL;
- if( display_date > 0 )
- p_subpic = spu_SortSubpictures( p_vout->p_spu, display_date,
- p_vout->p->b_paused, b_snapshot );
+ if( spu_render_time > 1 )
+ p_subpic = spu_SortSubpictures( p_vout->p_spu,
+ spu_render_time, b_snapshot );
/*
* Perform rendering
*/
p_vout->p->i_picture_displayed++;
/*
* Perform rendering
*/
p_vout->p->i_picture_displayed++;
- p_directbuffer = vout_RenderPicture( p_vout, p_filtered_picture,
- p_subpic, p_vout->p->b_paused );
+ p_directbuffer = vout_RenderPicture( p_vout,
+ p_filtered_picture, p_subpic,
+ spu_render_time );
/*
* Take a snapshot if requested
/*
* Take a snapshot if requested
/* DO NOT use vout_RenderPicture unless you are in src/video_ouput */
picture_t *vout_RenderPicture( vout_thread_t *, picture_t *,
/* DO NOT use vout_RenderPicture unless you are in src/video_ouput */
picture_t *vout_RenderPicture( vout_thread_t *, picture_t *,
- subpicture_t *, bool b_paused );
+ subpicture_t *,
+ mtime_t render_date );
/* DO NOT use vout_UsePictureLocked unless you are in src/video_ouput
*
/* DO NOT use vout_UsePictureLocked unless you are in src/video_ouput
*
* thread which direct buffer needs to be displayed.
*/
picture_t *vout_RenderPicture( vout_thread_t *p_vout, picture_t *p_pic,
* thread which direct buffer needs to be displayed.
*/
picture_t *vout_RenderPicture( vout_thread_t *p_vout, picture_t *p_pic,
- subpicture_t *p_subpic, bool b_paused )
+ subpicture_t *p_subpic, mtime_t render_date )
{
if( p_pic == NULL )
return NULL;
{
if( p_pic == NULL )
return NULL;
spu_RenderSubpictures( p_vout->p_spu,
PP_OUTPUTPICTURE[0], &p_vout->fmt_out,
spu_RenderSubpictures( p_vout->p_spu,
PP_OUTPUTPICTURE[0], &p_vout->fmt_out,
- p_subpic, &p_vout->fmt_in, b_paused );
+ p_subpic, &p_vout->fmt_in, render_date );
vout_UnlockPicture( p_vout, PP_OUTPUTPICTURE[0] );
vout_UnlockPicture( p_vout, PP_OUTPUTPICTURE[0] );
picture_Copy( PP_OUTPUTPICTURE[0], p_pic );
spu_RenderSubpictures( p_vout->p_spu,
PP_OUTPUTPICTURE[0], &p_vout->fmt_out,
picture_Copy( PP_OUTPUTPICTURE[0], p_pic );
spu_RenderSubpictures( p_vout->p_spu,
PP_OUTPUTPICTURE[0], &p_vout->fmt_out,
- p_subpic, &p_vout->fmt_in, b_paused );
+ p_subpic, &p_vout->fmt_in, render_date );
vout_UnlockPicture( p_vout, PP_OUTPUTPICTURE[0] );
vout_UnlockPicture( p_vout, PP_OUTPUTPICTURE[0] );
/* Render subpictures on the first direct buffer */
spu_RenderSubpictures( p_vout->p_spu,
p_tmp_pic, &p_vout->fmt_out,
/* Render subpictures on the first direct buffer */
spu_RenderSubpictures( p_vout->p_spu,
p_tmp_pic, &p_vout->fmt_out,
- p_subpic, &p_vout->fmt_in, b_paused );
+ p_subpic, &p_vout->fmt_in, render_date );
if( vout_LockPicture( p_vout, &p_vout->p_picture[0] ) )
return NULL;
if( vout_LockPicture( p_vout, &p_vout->p_picture[0] ) )
return NULL;
/* Render subpictures on the first direct buffer */
spu_RenderSubpictures( p_vout->p_spu,
&p_vout->p_picture[0], &p_vout->fmt_out,
/* Render subpictures on the first direct buffer */
spu_RenderSubpictures( p_vout->p_spu,
&p_vout->p_picture[0], &p_vout->fmt_out,
- p_subpic, &p_vout->fmt_in, b_paused );
+ p_subpic, &p_vout->fmt_in, render_date );
}
vout_UnlockPicture( p_vout, &p_vout->p_picture[0] );
}
vout_UnlockPicture( p_vout, &p_vout->p_picture[0] );
subpicture_t *, subpicture_region_t *,
const spu_scale_t scale_size,
const video_format_t *p_fmt,
subpicture_t *, subpicture_region_t *,
const spu_scale_t scale_size,
const video_format_t *p_fmt,
- const spu_area_t *p_subtitle_area, int i_subtitle_area );
+ const spu_area_t *p_subtitle_area, int i_subtitle_area,
+ mtime_t render_date );
static void UpdateSPU ( spu_t *, vlc_object_t * );
static int CropCallback( vlc_object_t *, char const *,
static void UpdateSPU ( spu_t *, vlc_object_t * );
static int CropCallback( vlc_object_t *, char const *,
void spu_RenderSubpictures( spu_t *p_spu,
picture_t *p_pic_dst, const video_format_t *p_fmt_dst,
subpicture_t *p_subpic_list,
void spu_RenderSubpictures( spu_t *p_spu,
picture_t *p_pic_dst, const video_format_t *p_fmt_dst,
subpicture_t *p_subpic_list,
- const video_format_t *p_fmt_src, bool b_paused )
+ const video_format_t *p_fmt_src,
+ mtime_t render_date )
{
spu_private_t *p_sys = p_spu->p;
{
spu_private_t *p_sys = p_spu->p;
+ const mtime_t system_date = mdate();
+
const int i_source_video_width = p_fmt_src->i_width;
const int i_source_video_height = p_fmt_src->i_height;
const int i_source_video_width = p_fmt_src->i_width;
const int i_source_video_height = p_fmt_src->i_height;
- const mtime_t i_current_date = mdate();
unsigned int i_subpicture;
subpicture_t *pp_subpicture[VOUT_MAX_SUBPICTURES];
unsigned int i_subpicture;
subpicture_t *pp_subpicture[VOUT_MAX_SUBPICTURES];
p_subpic != NULL;
p_subpic = p_subpic->p_next )
{
p_subpic != NULL;
p_subpic = p_subpic->p_next )
{
- /* */
- if( !b_paused && p_subpic->pf_pre_render )
+ /* TODO remove pre-render */
+ if( p_subpic->pf_pre_render )
p_subpic->pf_pre_render( p_spu, p_subpic, p_fmt_dst );
p_subpic->pf_pre_render( p_spu, p_subpic, p_fmt_dst );
- if( !b_paused && p_subpic->pf_update_regions )
+ if( p_subpic->pf_update_regions )
{
video_format_t fmt_org = *p_fmt_dst;
fmt_org.i_width =
{
video_format_t fmt_org = *p_fmt_dst;
fmt_org.i_width =
fmt_org.i_height =
fmt_org.i_visible_height = i_source_video_height;
fmt_org.i_height =
fmt_org.i_visible_height = i_source_video_height;
- p_subpic->pf_update_regions( p_spu, p_subpic, &fmt_org, i_current_date );
+ p_subpic->pf_update_regions( p_spu, p_subpic, &fmt_org,
+ p_subpic->b_subtitle ? render_date : system_date );
/* */
SpuRenderRegion( p_spu, p_pic_dst, &area,
p_subpic, p_region, scale, p_fmt_dst,
/* */
SpuRenderRegion( p_spu, p_pic_dst, &area,
p_subpic, p_region, scale, p_fmt_dst,
- p_subtitle_area, i_subtitle_area );
+ p_subtitle_area, i_subtitle_area,
+ p_subpic->b_subtitle ? render_date : system_date );
if( p_subpic->b_subtitle )
{
if( p_subpic->b_subtitle )
{
* to be removed if a newer one is available), which makes it a lot
* more difficult to guess if a subpicture has to be rendered or not.
*****************************************************************************/
* to be removed if a newer one is available), which makes it a lot
* more difficult to guess if a subpicture has to be rendered or not.
*****************************************************************************/
-subpicture_t *spu_SortSubpictures( spu_t *p_spu, mtime_t display_date,
- bool b_paused, bool b_subtitle_only )
+subpicture_t *spu_SortSubpictures( spu_t *p_spu, mtime_t render_date,
+ bool b_subtitle_only )
{
spu_private_t *p_sys = p_spu->p;
int i_channel;
subpicture_t *p_subpic = NULL;
{
spu_private_t *p_sys = p_spu->p;
int i_channel;
subpicture_t *p_subpic = NULL;
+ const mtime_t system_date = mdate();
/* Update sub-filter chain */
vlc_mutex_lock( &p_sys->lock );
/* Update sub-filter chain */
vlc_mutex_lock( &p_sys->lock );
}
/* Run subpicture filters */
}
/* Run subpicture filters */
- filter_chain_SubFilter( p_sys->p_chain, display_date );
+ filter_chain_SubFilter( p_sys->p_chain, render_date );
vlc_mutex_lock( &p_sys->lock );
vlc_mutex_lock( &p_sys->lock );
bool pb_available_late[VOUT_MAX_SUBPICTURES];
int i_available = 0;
bool pb_available_late[VOUT_MAX_SUBPICTURES];
int i_available = 0;
- mtime_t start_date = display_date;
- mtime_t ephemer_date = 0;
+ mtime_t start_date = render_date;
+ mtime_t ephemer_subtitle_date = 0;
+ mtime_t ephemer_system_date = 0;
int i_index;
/* Select available pictures */
int i_index;
/* Select available pictures */
- if( display_date &&
- display_date < p_current->i_start )
+ if( render_date &&
+ render_date < p_current->i_start )
{
/* Too early, come back next monday */
continue;
}
{
/* Too early, come back next monday */
continue;
}
- if( p_current->i_start > ephemer_date )
- ephemer_date = p_current->i_start;
+ mtime_t *pi_ephemer_date = p_current->b_subtitle ? &ephemer_subtitle_date : &ephemer_system_date;
+ if( p_current->i_start > *pi_ephemer_date )
+ *pi_ephemer_date = p_current->i_start;
- b_stop_valid = ( !p_current->b_ephemer || p_current->i_stop > p_current->i_start ) &&
- ( !p_current->b_subtitle || !b_paused ); /* XXX Assume that subtitle are pausable */
+ b_stop_valid = !p_current->b_ephemer || p_current->i_stop > p_current->i_start;
- b_late = b_stop_valid && p_current->i_stop <= display_date;
+ b_late = b_stop_valid && p_current->i_stop <= p_current->b_subtitle ? render_date : system_date;
/* start_date will be used for correct automatic overlap support
* in case picture that should not be displayed anymore (display_time)
* overlap with a picture to be displayed (p_current->i_start) */
/* start_date will be used for correct automatic overlap support
* in case picture that should not be displayed anymore (display_time)
* overlap with a picture to be displayed (p_current->i_start) */
- if( !b_late && !p_current->b_ephemer )
+ if( p_current->b_subtitle && !b_late && !p_current->b_ephemer )
start_date = p_current->i_start;
/* */
start_date = p_current->i_start;
/* */
subpicture_t *p_current = p_available_subpic[i_index];
bool b_late = pb_available_late[i_index];
subpicture_t *p_current = p_available_subpic[i_index];
bool b_late = pb_available_late[i_index];
- if( ( b_late && p_current->i_stop <= __MAX( start_date, p_sys->i_last_sort_date ) ) ||
+ const mtime_t stop_date = p_current->b_subtitle ? __MAX( start_date, p_sys->i_last_sort_date ) : system_date;
+ const mtime_t ephemer_date = p_current->b_subtitle ? ephemer_subtitle_date : ephemer_system_date;
+
+ if( ( b_late && p_current->i_stop <= stop_date ) ||
( p_current->b_ephemer && p_current->i_start < ephemer_date ) )
{
/* Destroy late and obsolete ephemer subpictures */
( p_current->b_ephemer && p_current->i_start < ephemer_date ) )
{
/* Destroy late and obsolete ephemer subpictures */
- p_sys->i_last_sort_date = display_date;
+ p_sys->i_last_sort_date = render_date;
vlc_mutex_unlock( &p_sys->lock );
return p_subpic;
vlc_mutex_unlock( &p_sys->lock );
return p_subpic;
static void SpuRenderText( spu_t *p_spu, bool *pb_rerender_text,
subpicture_t *p_subpic, subpicture_region_t *p_region,
static void SpuRenderText( spu_t *p_spu, bool *pb_rerender_text,
subpicture_t *p_subpic, subpicture_region_t *p_region,
- int i_min_scale_ratio )
+ int i_min_scale_ratio, mtime_t render_date )
{
filter_t *p_text = p_spu->p->p_text;
{
filter_t *p_text = p_spu->p->p_text;
* the text over time.
*/
var_SetTime( p_text, "spu-duration", p_subpic->i_stop - p_subpic->i_start );
* the text over time.
*/
var_SetTime( p_text, "spu-duration", p_subpic->i_stop - p_subpic->i_start );
- var_SetTime( p_text, "spu-elapsed", mdate() - p_subpic->i_start );
+ var_SetTime( p_text, "spu-elapsed", render_date );
var_SetBool( p_text, "text-rerender", false );
var_SetInteger( p_text, "scale", i_min_scale_ratio );
var_SetBool( p_text, "text-rerender", false );
var_SetInteger( p_text, "scale", i_min_scale_ratio );
subpicture_t *p_subpic, subpicture_region_t *p_region,
const spu_scale_t scale_size,
const video_format_t *p_fmt,
subpicture_t *p_subpic, subpicture_region_t *p_region,
const spu_scale_t scale_size,
const video_format_t *p_fmt,
- const spu_area_t *p_subtitle_area, int i_subtitle_area )
+ const spu_area_t *p_subtitle_area, int i_subtitle_area,
+ mtime_t render_date )
{
spu_private_t *p_sys = p_spu->p;
{
spu_private_t *p_sys = p_spu->p;
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) */
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 );
+ SpuRenderText( p_spu, &b_rerender_text, p_subpic, p_region,
+ i_min_scale_ratio, render_date );
b_restore_format = b_rerender_text;
/* Check if the rendering has failed ... */
b_restore_format = b_rerender_text;
/* Check if the rendering has failed ... */