Commit 6bd606ac authored by Laurent Aimar's avatar Laurent Aimar

Spu pause support.

Now SSA subtitle pause is working even with karaoke.
parent bea1c07c
......@@ -87,7 +87,7 @@ struct subpicture_sys_t
decoder_t *p_dec;
void *p_subs_data;
int i_subs_len;
mtime_t i_stream_system_delta;
mtime_t i_pts;
};
/*****************************************************************************
......@@ -202,8 +202,7 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
}
memcpy( p_spu->p_sys->p_subs_data, p_block->p_buffer,
p_block->i_buffer );
p_spu->p_sys->i_stream_system_delta =
p_block->i_pts - decoder_GetDisplayDate( p_dec, p_block->i_pts );
p_spu->p_sys->i_pts = p_block->i_pts;
p_spu->i_start = p_block->i_pts;
p_spu->i_stop = p_block->i_pts + p_block->i_length;
......@@ -304,12 +303,14 @@ static void UpdateRegions( spu_t *p_spu, subpicture_t *p_subpic,
memset( p_spu_region->p_picture->Y_PIXELS, 0x00, p_spu_region->p_picture->Y_PITCH * p_sys->fmt_cached.i_height );
/* */
const mtime_t i_stream_date = p_subpic->p_sys->i_pts + (i_ts - p_subpic->i_start);
//msg_Dbg( p_dec, "TS %lf", ts * 0.000001 );
memset( &csri_frame, 0, sizeof(csri_frame) );
csri_frame.pixfmt = CSRI_F_BGRA;
csri_frame.planes[0] = (unsigned char*)p_spu_region->p_picture->Y_PIXELS;
csri_frame.strides[0] = p_spu_region->p_picture->Y_PITCH;
csri_render( p_sys->p_instance, &csri_frame, (i_ts + p_subpic->p_sys->i_stream_system_delta) * 0.000001 );
csri_render( p_sys->p_instance, &csri_frame, i_stream_date * 0.000001 );
}
}
......@@ -105,7 +105,7 @@ struct subpicture_sys_t
decoder_sys_t *p_dec_sys;
void *p_subs_data;
int i_subs_len;
mtime_t i_stream_system_delta;
mtime_t i_pts;
};
typedef struct
......@@ -257,8 +257,7 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
}
memcpy( p_spu->p_sys->p_subs_data, p_block->p_buffer,
p_block->i_buffer );
p_spu->p_sys->i_stream_system_delta =
p_block->i_pts - decoder_GetDisplayDate( p_dec, p_block->i_pts );
p_spu->p_sys->i_pts = p_block->i_pts;
p_spu->i_start = p_block->i_pts;
p_spu->i_stop = p_block->i_pts + p_block->i_length;
......@@ -341,9 +340,10 @@ static void UpdateRegions( spu_t *p_spu, subpicture_t *p_subpic,
}
/* */
const mtime_t i_stream_date = p_subpic->p_sys->i_pts + (i_ts - p_subpic->i_start);
int i_changed;
ass_image_t *p_img = ass_render_frame( p_ass->p_renderer, p_sys->p_track,
(i_ts + p_subpic->p_sys->i_stream_system_delta)/1000, &i_changed );
i_stream_date/1000, &i_changed );
if( !i_changed && !b_fmt_changed )
{
......
......@@ -692,9 +692,10 @@ static void DecoderOutputChangePause( decoder_t *p_dec, bool b_paused, mtime_t i
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
if( p_dec->i_object_type == VLC_OBJECT_PACKETIZER )
return;
/* XXX only audio and video output have to be paused.
* - for sout it is useless
* - for subs, it is done by the vout
*/
if( p_dec->fmt_in.i_cat == AUDIO_ES )
{
// TODO
......@@ -706,10 +707,6 @@ static void DecoderOutputChangePause( decoder_t *p_dec, bool b_paused, mtime_t i
if( p_owner->p_vout )
vout_ChangePause( p_owner->p_vout, b_paused, i_date );
}
else if( p_dec->fmt_in.i_cat == SPU_ES )
{
/* XXX is it needed, maybe the vout should simply pause it */
}
}
static inline void DecoderUpdatePreroll( int64_t *pi_preroll, const block_t *p )
{
......
......@@ -599,7 +599,7 @@ void vout_ChangePause( vout_thread_t *p_vout, bool b_paused, mtime_t i_date )
if( p_pic->i_status == READY_PICTURE )
p_pic->date += i_duration;
}
// TODO spu
spu_OffsetSubtitleDate( p_vout->p_spu, i_duration );
}
p_vout->p->b_paused = b_paused;
p_vout->p->i_pause_date = i_date;
......@@ -1007,22 +1007,16 @@ static void* RunThread( vlc_object_t *p_this )
/*
* Check for subpictures to display
*/
bool b_paused = false;
if( display_date > 0 )
{
p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT, FIND_PARENT );
b_paused = p_input && var_GetInteger( p_input, "state" ) == PAUSE_S;
if( p_input )
vlc_object_release( p_input );
p_subpic = spu_SortSubpictures( p_vout->p_spu, display_date, b_paused, b_snapshot );
}
p_subpic = spu_SortSubpictures( p_vout->p_spu, display_date,
p_vout->p->b_paused, b_snapshot );
/*
* Perform rendering
*/
i_displayed++;
p_directbuffer = vout_RenderPicture( p_vout, p_filtered_picture, p_subpic, b_paused );
p_directbuffer = vout_RenderPicture( p_vout, p_filtered_picture,
p_subpic, p_vout->p->b_paused );
/*
* Take a snapshot if requested
......
......@@ -96,5 +96,10 @@ int vout_CountPictureAvailable( vout_thread_t * );
*/
void vout_ChangePause( vout_thread_t *, bool b_paused, mtime_t i_date );
/**
* This function will apply an offset on subtitle subpicture.
*/
void spu_OffsetSubtitleDate( spu_t *p_spu, mtime_t i_duration );
#endif
......@@ -36,6 +36,7 @@
#include <vlc_filter.h>
#include <vlc_osd.h>
#include "../libvlc.h"
#include "vout_internal.h"
#include <assert.h>
#include <limits.h>
......@@ -90,6 +91,8 @@ struct spu_private_t
/* */
mtime_t i_last_sort_date;
/* */
mtime_t i_last_render_date;
};
/* */
......@@ -228,6 +231,7 @@ spu_t *__spu_Create( vlc_object_t *p_this )
/* */
p_sys->i_last_sort_date = -1;
p_sys->i_last_render_date = -1;
return p_spu;
}
......@@ -394,13 +398,18 @@ void spu_RenderSubpictures( spu_t *p_spu,
if( !b_paused && p_subpic->pf_update_regions )
{
mtime_t i_render_date;
video_format_t fmt_org = *p_fmt_dst;
fmt_org.i_width =
fmt_org.i_visible_width = i_source_video_width;
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 );
i_render_date = i_current_date;
if( p_subpic->b_subtitle && b_paused && p_sys->i_last_render_date > 0 )
i_render_date = p_sys->i_last_render_date;
p_subpic->pf_update_regions( p_spu, p_subpic, &fmt_org, i_render_date );
}
/* */
......@@ -414,6 +423,9 @@ void spu_RenderSubpictures( spu_t *p_spu,
pp_subpicture[i_subpicture++] = p_subpic;
}
if( !b_paused )
p_sys->i_last_render_date = i_current_date;
/* Be sure we have at least 1 picture to process */
if( i_subpicture <= 0 )
{
......@@ -655,6 +667,27 @@ subpicture_t *spu_SortSubpictures( spu_t *p_spu, mtime_t display_date,
return p_subpic;
}
void spu_OffsetSubtitleDate( spu_t *p_spu, mtime_t i_duration )
{
spu_private_t *p_sys = p_spu->p;
vlc_mutex_lock( &p_sys->lock );
for( int i = 0; i < VOUT_MAX_SUBPICTURES; i++ )
{
spu_heap_entry_t *p_entry = &p_sys->heap.p_entry[i];
subpicture_t *p_current = p_entry->p_subpicture;
if( p_current && p_current->b_subtitle )
{
if( p_current->i_start > 0 )
p_current->i_start += i_duration;
if( p_current->i_stop > 0 )
p_current->i_stop += i_duration;
}
}
vlc_mutex_unlock( &p_sys->lock );
}
/*****************************************************************************
* subpicture_t allocation
*****************************************************************************/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment