[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