[vlc-commits] transcode: rework passing subpictures

Francois Cartegnie git at videolan.org
Mon Jul 9 16:15:53 CEST 2018


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Thu Jul  5 11:40:20 2018 +0200| [a9f75a57bbeb6c72b202efb1663669835759d527] | committer: Francois Cartegnie

transcode: rework passing subpictures

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=a9f75a57bbeb6c72b202efb1663669835759d527
---

 modules/stream_out/transcode/spu.c       |  9 +++++-
 modules/stream_out/transcode/transcode.c | 48 +++++++++++++++++++++++---------
 modules/stream_out/transcode/transcode.h | 12 +++++++-
 modules/stream_out/transcode/video.c     | 31 +++++++++++++++++----
 4 files changed, 79 insertions(+), 21 deletions(-)

diff --git a/modules/stream_out/transcode/spu.c b/modules/stream_out/transcode/spu.c
index fb1f1396aa..5cfac214e1 100644
--- a/modules/stream_out/transcode/spu.c
+++ b/modules/stream_out/transcode/spu.c
@@ -189,7 +189,14 @@ int transcode_spu_process( sout_stream_t *p_stream,
         }
 
         if( p_sys->b_soverlay )
-            spu_PutSubpicture( p_sys->p_spu, p_subpic );
+        {
+            if( !id->pf_send_subpicture )
+            {
+                subpicture_Delete( p_subpic );
+                b_error = true;
+            }
+            else id->pf_send_subpicture( id->callback_data, p_subpic );
+        }
         else
         {
             block_t *p_block;
diff --git a/modules/stream_out/transcode/transcode.c b/modules/stream_out/transcode/transcode.c
index c0db88fae3..c0da2f8840 100644
--- a/modules/stream_out/transcode/transcode.c
+++ b/modules/stream_out/transcode/transcode.c
@@ -424,6 +424,13 @@ static int Open( vlc_object_t *p_this )
         free( psz_string );
     }
 
+    /* Subpictures SOURCES parameters (not releated to subtitles stream) */
+    psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "sfilter" );
+    if( psz_string && *psz_string )
+        p_sys->vfilters_cfg.video.psz_spu_sources = psz_string;
+    else
+        free( psz_string );
+
     /* Subpictures transcoding parameters */
     sout_encoder_config_init( &p_sys->senc_cfg );
 
@@ -435,17 +442,6 @@ static int Open( vlc_object_t *p_this )
     /* Set default size for TEXT spu non overlay conversion / updater */
     p_sys->senc_cfg.spu.i_width = (p_sys->venc_cfg.video.i_width) ? p_sys->venc_cfg.video.i_width : 1280;
     p_sys->senc_cfg.spu.i_height = (p_sys->venc_cfg.video.i_height) ? p_sys->venc_cfg.video.i_height : 720;
-    if( p_sys->b_soverlay )
-        p_sys->p_spu = spu_Create( p_stream, NULL );
-
-    /* Subpictures SOURCES parameters (not releated to SPU stream) */
-    psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "sfilter" );
-    if( psz_string && *psz_string )
-    {
-        if( !p_sys->p_spu || (p_sys->p_spu = spu_Create( p_stream, NULL )) )
-            spu_ChangeSources( p_sys->p_spu, psz_string );
-    }
-    free( psz_string );
 
     p_stream->pf_add    = Add;
     p_stream->pf_del    = Del;
@@ -471,8 +467,6 @@ static void Close( vlc_object_t * p_this )
 
     sout_encoder_config_clean( &p_sys->senc_cfg );
 
-    if( p_sys->p_spu ) spu_Destroy( p_sys->p_spu );
-
     free( p_sys );
 }
 
@@ -499,6 +493,17 @@ static void DeleteSoutStreamID( sout_stream_id_sys_t *id )
     }
 }
 
+static void SendSpuToVideoCallback( void *cbdata, subpicture_t *p_subpicture )
+{
+    sout_stream_t *p_stream = cbdata;
+    sout_stream_sys_t *p_sys = p_stream->p_sys;
+    if( !p_sys->id_video )
+        subpicture_Delete( p_subpicture );
+    else
+        transcode_video_push_spu( p_stream,
+                                  p_sys->id_video, p_subpicture );
+}
+
 static void *Add( sout_stream_t *p_stream, const es_format_t *p_fmt )
 {
     sout_stream_sys_t *p_sys = p_stream->p_sys;
@@ -525,6 +530,16 @@ static void *Add( sout_stream_t *p_stream, const es_format_t *p_fmt )
     es_format_Copy( &id->p_decoder->fmt_in, p_fmt );
     id->p_decoder->b_frame_drop_allowed = false;
 
+    switch( p_fmt->i_cat )
+    {
+        case SPU_ES:
+            id->pf_send_subpicture = SendSpuToVideoCallback;
+            id->callback_data = p_stream;
+            break;
+        default:
+            break;
+    }
+
     /* Create encoder object */
     id->p_encoder = sout_EncoderCreate( p_stream );
     if( !id->p_encoder )
@@ -547,7 +562,11 @@ static void *Add( sout_stream_t *p_stream, const es_format_t *p_fmt )
     if( p_fmt->i_cat == AUDIO_ES && p_sys->aenc_cfg.i_codec )
         success = transcode_audio_add(p_stream, p_fmt, id);
     else if( p_fmt->i_cat == VIDEO_ES && p_sys->venc_cfg.i_codec )
+    {
         success = transcode_video_add(p_stream, p_fmt, id);
+        if( success && !p_sys->id_video )
+            p_sys->id_video = id;
+    }
     else if( ( p_fmt->i_cat == SPU_ES ) &&
              ( p_sys->senc_cfg.i_codec || p_sys->b_soverlay ) )
         success = transcode_spu_add(p_stream, p_fmt, id);
@@ -573,6 +592,7 @@ error:
 
 static void Del( sout_stream_t *p_stream, void *_id )
 {
+    sout_stream_sys_t *p_sys = p_stream->p_sys;
     sout_stream_id_sys_t *id = (sout_stream_id_sys_t *)_id;
     if( id->b_transcode )
     {
@@ -584,6 +604,8 @@ static void Del( sout_stream_t *p_stream, void *_id )
             break;
         case VIDEO_ES:
             Send( p_stream, id, NULL );
+            if( id == p_sys->id_video )
+                p_sys->id_video = NULL;
             transcode_video_close( p_stream, id );
             break;
         case SPU_ES:
diff --git a/modules/stream_out/transcode/transcode.h b/modules/stream_out/transcode/transcode.h
index 8b9254f225..339e308574 100644
--- a/modules/stream_out/transcode/transcode.h
+++ b/modules/stream_out/transcode/transcode.h
@@ -17,6 +17,7 @@ typedef struct
         {
             char            *psz_deinterlace;
             config_chain_t  *p_deinterlace_cfg;
+            char            *psz_spu_sources;
         } video;
     };
 } sout_filters_config_t;
@@ -36,6 +37,7 @@ void sout_filters_config_clean( sout_filters_config_t *p_cfg )
         free( p_cfg->video.psz_deinterlace );
         config_ChainDestroy( p_cfg->video.p_deinterlace_cfg );
     }
+    free( p_cfg->video.psz_spu_sources );
 }
 
 typedef struct
@@ -92,7 +94,7 @@ void sout_encoder_config_clean( sout_encoder_config_t *p_cfg )
 typedef struct
 {
     sout_stream_id_sys_t *id_video;
-    spu_t                *p_spu;
+
     bool                  b_soverlay;
 
     /* Audio */
@@ -147,11 +149,18 @@ struct sout_stream_id_sys_t
 
     union
     {
+        void (*pf_send_subpicture)(void *cbdata, subpicture_t *);
+    };
+    void *callback_data;
+
+    union
+    {
          struct
          {
              filter_chain_t  *p_f_chain; /**< Video filters */
              filter_chain_t  *p_uf_chain; /**< User-specified video filters */
              filter_t        *p_spu_blender;
+             spu_t           *p_spu;
              video_format_t  fmt_input_video;
              video_format_t  video_dec_out; /* only rw from pf_vout_format_update() */
          };
@@ -214,5 +223,6 @@ bool transcode_audio_add    ( sout_stream_t *, const es_format_t *,
 void transcode_video_close  ( sout_stream_t *, sout_stream_id_sys_t * );
 int  transcode_video_process( sout_stream_t *, sout_stream_id_sys_t *,
                                      block_t *, block_t ** );
+void transcode_video_push_spu( sout_stream_t *, sout_stream_id_sys_t *, subpicture_t * );
 bool transcode_video_add    ( sout_stream_t *, const es_format_t *,
                                 sout_stream_id_sys_t *);
diff --git a/modules/stream_out/transcode/video.c b/modules/stream_out/transcode/video.c
index 0661965efc..a745fe7f11 100644
--- a/modules/stream_out/transcode/video.c
+++ b/modules/stream_out/transcode/video.c
@@ -290,7 +290,6 @@ static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_sys_t *i
      * of the encoder here.
      */
 
-    p_sys->id_video = id;
     id->pp_pics = picture_fifo_New();
     if( id->pp_pics == NULL )
     {
@@ -364,6 +363,13 @@ static void transcode_video_filter_init( sout_stream_t *p_stream,
         p_src = filter_chain_GetFmtOut( id->p_f_chain );
     }
 
+    /* SPU Sources */
+    if( p_cfg->video.psz_spu_sources )
+    {
+        if( id->p_spu || (id->p_spu = spu_Create( p_stream, NULL )) )
+            spu_ChangeSources( id->p_spu, p_cfg->video.psz_spu_sources );
+    }
+
     if( b_master_sync )
     {
         filter_chain_AppendFilter( id->p_f_chain, "fps", NULL, p_src, p_dst );
@@ -729,17 +735,30 @@ void transcode_video_close( sout_stream_t *p_stream,
         filter_chain_Delete( id->p_uf_chain );
     if( id->p_spu_blender )
         filter_DeleteBlend( id->p_spu_blender );
+    if( id->p_spu )
+        spu_Destroy( id->p_spu );
+}
+
+void transcode_video_push_spu( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
+                               subpicture_t *p_subpicture )
+{
+    if( !id->p_spu )
+        id->p_spu = spu_Create( p_stream, NULL );
+    if( !id->p_spu )
+        subpicture_Delete( p_subpicture );
+    else
+        spu_PutSubpicture( id->p_spu, p_subpicture );
 }
 
 static picture_t * RenderSubpictures( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
                                        picture_t *p_pic )
 {
-    sout_stream_sys_t *p_sys = p_stream->p_sys;
+    VLC_UNUSED(p_stream);
 
-    /* Check if we have a subpicture to overlay */
-    if( !p_sys->p_spu )
+    if( !id->p_spu )
         return p_pic;
 
+    /* Check if we have a subpicture to overlay */
     video_format_t fmt, outfmt;
     vlc_mutex_lock( &id->fifo.lock );
     video_format_Copy( &outfmt, &id->video_dec_out );
@@ -753,7 +772,7 @@ static picture_t * RenderSubpictures( sout_stream_t *p_stream, sout_stream_id_sy
         fmt.i_y_offset       = 0;
     }
 
-    subpicture_t *p_subpic = spu_Render( p_sys->p_spu, NULL, &fmt,
+    subpicture_t *p_subpic = spu_Render( id->p_spu, NULL, &fmt,
                                          &outfmt,
                                          p_pic->date, p_pic->date, false );
 
@@ -773,7 +792,7 @@ static picture_t * RenderSubpictures( sout_stream_t *p_stream, sout_stream_id_sy
             }
         }
         if( unlikely( !id->p_spu_blender ) )
-            id->p_spu_blender = filter_NewBlend( VLC_OBJECT( p_sys->p_spu ), &fmt );
+            id->p_spu_blender = filter_NewBlend( VLC_OBJECT( id->p_spu ), &fmt );
         if( likely( id->p_spu_blender ) )
             picture_BlendSubpicture( p_pic, id->p_spu_blender, p_subpic );
         subpicture_Delete( p_subpic );



More information about the vlc-commits mailing list