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 ...@@ -87,7 +87,7 @@ struct subpicture_sys_t
decoder_t *p_dec; decoder_t *p_dec;
void *p_subs_data; void *p_subs_data;
int i_subs_len; 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 ) ...@@ -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, memcpy( p_spu->p_sys->p_subs_data, p_block->p_buffer,
p_block->i_buffer ); p_block->i_buffer );
p_spu->p_sys->i_stream_system_delta = p_spu->p_sys->i_pts = p_block->i_pts;
p_block->i_pts - decoder_GetDisplayDate( p_dec, p_block->i_pts );
p_spu->i_start = p_block->i_pts; p_spu->i_start = p_block->i_pts;
p_spu->i_stop = p_block->i_pts + p_block->i_length; 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, ...@@ -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 ); 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 ); //msg_Dbg( p_dec, "TS %lf", ts * 0.000001 );
memset( &csri_frame, 0, sizeof(csri_frame) ); memset( &csri_frame, 0, sizeof(csri_frame) );
csri_frame.pixfmt = CSRI_F_BGRA; csri_frame.pixfmt = CSRI_F_BGRA;
csri_frame.planes[0] = (unsigned char*)p_spu_region->p_picture->Y_PIXELS; 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_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 ...@@ -105,7 +105,7 @@ struct subpicture_sys_t
decoder_sys_t *p_dec_sys; decoder_sys_t *p_dec_sys;
void *p_subs_data; void *p_subs_data;
int i_subs_len; int i_subs_len;
mtime_t i_stream_system_delta; mtime_t i_pts;
}; };
typedef struct typedef struct
...@@ -257,8 +257,7 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -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, memcpy( p_spu->p_sys->p_subs_data, p_block->p_buffer,
p_block->i_buffer ); p_block->i_buffer );
p_spu->p_sys->i_stream_system_delta = p_spu->p_sys->i_pts = p_block->i_pts;
p_block->i_pts - decoder_GetDisplayDate( p_dec, p_block->i_pts );
p_spu->i_start = p_block->i_pts; p_spu->i_start = p_block->i_pts;
p_spu->i_stop = p_block->i_pts + p_block->i_length; 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, ...@@ -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; int i_changed;
ass_image_t *p_img = ass_render_frame( p_ass->p_renderer, p_sys->p_track, 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 ) if( !i_changed && !b_fmt_changed )
{ {
......
...@@ -692,9 +692,10 @@ static void DecoderOutputChangePause( decoder_t *p_dec, bool b_paused, mtime_t i ...@@ -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; decoder_owner_sys_t *p_owner = p_dec->p_owner;
if( p_dec->i_object_type == VLC_OBJECT_PACKETIZER ) /* XXX only audio and video output have to be paused.
return; * - for sout it is useless
* - for subs, it is done by the vout
*/
if( p_dec->fmt_in.i_cat == AUDIO_ES ) if( p_dec->fmt_in.i_cat == AUDIO_ES )
{ {
// TODO // TODO
...@@ -706,10 +707,6 @@ static void DecoderOutputChangePause( decoder_t *p_dec, bool b_paused, mtime_t i ...@@ -706,10 +707,6 @@ static void DecoderOutputChangePause( decoder_t *p_dec, bool b_paused, mtime_t i
if( p_owner->p_vout ) if( p_owner->p_vout )
vout_ChangePause( p_owner->p_vout, b_paused, i_date ); 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 ) 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 ) ...@@ -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 ) if( p_pic->i_status == READY_PICTURE )
p_pic->date += i_duration; 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->b_paused = b_paused;
p_vout->p->i_pause_date = i_date; p_vout->p->i_pause_date = i_date;
...@@ -1007,22 +1007,16 @@ static void* RunThread( vlc_object_t *p_this ) ...@@ -1007,22 +1007,16 @@ static void* RunThread( vlc_object_t *p_this )
/* /*
* Check for subpictures to display * Check for subpictures to display
*/ */
bool b_paused = false;
if( display_date > 0 ) if( display_date > 0 )
{ p_subpic = spu_SortSubpictures( p_vout->p_spu, display_date,
p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT, FIND_PARENT ); p_vout->p->b_paused, b_snapshot );
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 );
}
/* /*
* Perform rendering * Perform rendering
*/ */
i_displayed++; 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 * Take a snapshot if requested
......
...@@ -96,5 +96,10 @@ int vout_CountPictureAvailable( vout_thread_t * ); ...@@ -96,5 +96,10 @@ int vout_CountPictureAvailable( vout_thread_t * );
*/ */
void vout_ChangePause( vout_thread_t *, bool b_paused, mtime_t i_date ); 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 #endif
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <vlc_filter.h> #include <vlc_filter.h>
#include <vlc_osd.h> #include <vlc_osd.h>
#include "../libvlc.h" #include "../libvlc.h"
#include "vout_internal.h"
#include <assert.h> #include <assert.h>
#include <limits.h> #include <limits.h>
...@@ -90,6 +91,8 @@ struct spu_private_t ...@@ -90,6 +91,8 @@ struct spu_private_t
/* */ /* */
mtime_t i_last_sort_date; 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 ) ...@@ -228,6 +231,7 @@ spu_t *__spu_Create( vlc_object_t *p_this )
/* */ /* */
p_sys->i_last_sort_date = -1; p_sys->i_last_sort_date = -1;
p_sys->i_last_render_date = -1;
return p_spu; return p_spu;
} }
...@@ -394,13 +398,18 @@ void spu_RenderSubpictures( spu_t *p_spu, ...@@ -394,13 +398,18 @@ void spu_RenderSubpictures( spu_t *p_spu,
if( !b_paused && p_subpic->pf_update_regions ) if( !b_paused && p_subpic->pf_update_regions )
{ {
mtime_t i_render_date;
video_format_t fmt_org = *p_fmt_dst; video_format_t fmt_org = *p_fmt_dst;
fmt_org.i_width = fmt_org.i_width =
fmt_org.i_visible_width = i_source_video_width; fmt_org.i_visible_width = i_source_video_width;
fmt_org.i_height = fmt_org.i_height =
fmt_org.i_visible_height = i_source_video_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, ...@@ -414,6 +423,9 @@ void spu_RenderSubpictures( spu_t *p_spu,
pp_subpicture[i_subpicture++] = p_subpic; 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 */ /* Be sure we have at least 1 picture to process */
if( i_subpicture <= 0 ) if( i_subpicture <= 0 )
{ {
...@@ -655,6 +667,27 @@ subpicture_t *spu_SortSubpictures( spu_t *p_spu, mtime_t display_date, ...@@ -655,6 +667,27 @@ subpicture_t *spu_SortSubpictures( spu_t *p_spu, mtime_t display_date,
return p_subpic; 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 * 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