[vlc-devel] commit: Spu pause support. (Laurent Aimar )
git version control
git at videolan.org
Sun Sep 28 15:08:47 CEST 2008
vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Sun Sep 28 15:03:51 2008 +0200| [6bd606ac8db324a80663d3acf7668c30877a2dc2] | committer: Laurent Aimar
Spu pause support.
Now SSA subtitle pause is working even with karaoke.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6bd606ac8db324a80663d3acf7668c30877a2dc2
---
modules/codec/csri.c | 9 +++++----
modules/codec/libass.c | 8 ++++----
src/input/decoder.c | 11 ++++-------
src/video_output/video_output.c | 16 +++++-----------
src/video_output/vout_internal.h | 5 +++++
src/video_output/vout_subpictures.c | 35 ++++++++++++++++++++++++++++++++++-
6 files changed, 57 insertions(+), 27 deletions(-)
diff --git a/modules/codec/csri.c b/modules/codec/csri.c
index 9cb78ef..61ae9f4 100644
--- a/modules/codec/csri.c
+++ b/modules/codec/csri.c
@@ -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 );
}
}
diff --git a/modules/codec/libass.c b/modules/codec/libass.c
index fd4e160..e6b14da 100644
--- a/modules/codec/libass.c
+++ b/modules/codec/libass.c
@@ -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 )
{
diff --git a/src/input/decoder.c b/src/input/decoder.c
index 31c9586..51abd40 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -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 )
{
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index ca5bcd1..84e6627 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -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
diff --git a/src/video_output/vout_internal.h b/src/video_output/vout_internal.h
index 718b16f..6e4554e 100644
--- a/src/video_output/vout_internal.h
+++ b/src/video_output/vout_internal.h
@@ -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
diff --git a/src/video_output/vout_subpictures.c b/src/video_output/vout_subpictures.c
index c497198..3161e48 100644
--- a/src/video_output/vout_subpictures.c
+++ b/src/video_output/vout_subpictures.c
@@ -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
*****************************************************************************/
More information about the vlc-devel
mailing list