sout: allow to extract/pass captions on request
authorFrancois Cartegnie <fcvlcdev@free.fr>
Thu, 26 Jul 2018 19:10:25 +0000 (21:10 +0200)
committerFrancois Cartegnie <fcvlcdev@free.fr>
Wed, 10 Oct 2018 07:46:46 +0000 (09:46 +0200)
include/vlc_sout.h
src/input/decoder.c
src/stream_output/stream_output.c

index ea4113a..e363c58 100644 (file)
@@ -53,6 +53,7 @@ struct sout_instance_t
 
     /** count of output that can't control the space */
     int                 i_out_pace_nocontrol;
+    bool                b_wants_substreams;
 
     vlc_mutex_t         lock;
     sout_stream_t       *p_stream;
@@ -187,6 +188,7 @@ static inline int sout_MuxControl( sout_mux_t *p_mux, int i_query, ... )
 
 enum sout_stream_query_e {
     SOUT_STREAM_EMPTY,    /* arg1=bool *,       res=can fail (assume true) */
+    SOUT_STREAM_WANTS_SUBSTREAMS,  /* arg1=bool *, res=can fail (assume false) */
     SOUT_STREAM_ID_SPU_HIGHLIGHT,  /* arg1=void *, arg2=const vlc_spu_highlight_t *, res=can fail */
 };
 
index a280eac..b39c704 100644 (file)
@@ -138,6 +138,8 @@ struct decoder_owner
         bool b_supported;
         decoder_cc_desc_t desc;
         decoder_t *pp_decoder[MAX_CC_DECODERS];
+        bool b_sout_created;
+        sout_packetizer_input_t *p_sout_input;
     } cc;
 
     /* Delay */
@@ -894,6 +896,35 @@ static void DecoderProcessSout( decoder_t *p_dec, block_t *p_block )
 
             p_sout_block->p_next = NULL;
 
+            if( p_owner->p_sout->b_wants_substreams && p_dec->pf_get_cc )
+            {
+                if( p_owner->cc.p_sout_input ||
+                    !p_owner->cc.b_sout_created )
+                {
+                    decoder_cc_desc_t desc;
+                    block_t *p_cc = p_dec->pf_get_cc( p_dec, &desc );
+                    if( p_cc )
+                    {
+                        if(!p_owner->cc.b_sout_created)
+                        {
+                            es_format_t ccfmt;
+                            es_format_Init(&ccfmt, SPU_ES, VLC_CODEC_CEA608);
+                            ccfmt.i_group = p_owner->fmt.i_group;
+                            ccfmt.subs.cc.i_reorder_depth = desc.i_reorder_depth;
+                            p_owner->cc.p_sout_input = sout_InputNew( p_owner->p_sout, &ccfmt );
+                            es_format_Clean(&ccfmt);
+                            p_owner->cc.b_sout_created = true;
+                        }
+
+                        if( !p_owner->cc.p_sout_input ||
+                            sout_InputSendBuffer( p_owner->cc.p_sout_input, p_cc ) )
+                        {
+                            block_Release( p_cc );
+                        }
+                    }
+                }
+            }
+
             if( DecoderPlaySout( p_dec, p_sout_block ) == VLC_EGENERIC )
             {
                 msg_Err( p_dec, "cannot continue streaming due to errors with codec %4.4s",
@@ -1857,6 +1888,8 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
     p_owner->cc.desc.i_708_channels = 0;
     for( unsigned i = 0; i < MAX_CC_DECODERS; i++ )
         p_owner->cc.pp_decoder[i] = NULL;
+    p_owner->cc.p_sout_input = NULL;
+    p_owner->cc.b_sout_created = false;
     p_owner->i_ts_delay = 0;
     return p_dec;
 }
@@ -1885,6 +1918,8 @@ static void DeleteDecoder( decoder_t * p_dec )
     if( p_owner->p_sout_input )
     {
         sout_InputDelete( p_owner->p_sout_input );
+        if( p_owner->cc.p_sout_input )
+            sout_InputDelete( p_owner->cc.p_sout_input );
     }
 #endif
 
index 07508e1..c09993f 100644 (file)
@@ -110,6 +110,7 @@ sout_instance_t *sout_NewInstance( vlc_object_t *p_parent, const char *psz_dest
     /* *** init descriptor *** */
     p_sout->psz_sout    = strdup( psz_dest );
     p_sout->i_out_pace_nocontrol = 0;
+    p_sout->b_wants_substreams = false;
 
     vlc_mutex_init( &p_sout->lock );
     p_sout->p_stream = NULL;
@@ -120,6 +121,9 @@ sout_instance_t *sout_NewInstance( vlc_object_t *p_parent, const char *psz_dest
     if( p_sout->p_stream )
     {
         free( psz_chain );
+        sout_StreamControl( p_sout->p_stream,
+                            SOUT_STREAM_WANTS_SUBSTREAMS,
+                            &p_sout->b_wants_substreams );
         return p_sout;
     }