]> git.sesse.net Git - vlc/blobdiff - src/stream_output/stream_output.c
Added sout-mux-caching option. It allow to set the initial muxer cache value
[vlc] / src / stream_output / stream_output.c
index adbb23d8fd122b68d010be81ecce40540a67c33e..2d512e664eafad2a7bf2f56c3f8f026b9290be7e 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * stream_output.c : stream output module
  *****************************************************************************
- * Copyright (C) 2002-2004 the VideoLAN team
+ * Copyright (C) 2002-2007 the VideoLAN team
  * $Id$
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
 
 #include <stdlib.h>                                                /* free() */
 #include <stdio.h>                                              /* sprintf() */
-#include <string.h>                                            /* strerror() */
+#include <string.h>
 
 #include <vlc_sout.h>
+#include <vlc_playlist.h>
 
 #include "stream_output.h"
 
@@ -72,46 +73,6 @@ static void mrl_Clean( mrl_t *p_mrl );
 sout_instance_t *__sout_NewInstance( vlc_object_t *p_parent, char * psz_dest )
 {
     sout_instance_t *p_sout;
-    vlc_value_t keep;
-
-    if( var_Get( p_parent, "sout-keep", &keep ) < 0 )
-    {
-        msg_Warn( p_parent, "cannot get sout-keep value" );
-        keep.b_bool = VLC_FALSE;
-    }
-    if( keep.b_bool )
-    {
-        if( ( p_sout = vlc_object_find( p_parent, VLC_OBJECT_SOUT,
-                                        FIND_ANYWHERE ) ) != NULL )
-        {
-            if( !strcmp( p_sout->psz_sout, psz_dest ) )
-            {
-                msg_Dbg( p_parent, "sout keep: reusing sout" );
-                msg_Dbg( p_parent, "sout keep: you probably want to use "
-                          "gather stream_out" );
-                vlc_object_detach( p_sout );
-                vlc_object_attach( p_sout, p_parent );
-                vlc_object_release( p_sout );
-                return p_sout;
-            }
-            else
-            {
-                msg_Dbg( p_parent, "sout keep: destroying unusable sout" );
-                vlc_object_release( p_sout );
-                sout_DeleteInstance( p_sout );
-            }
-        }
-    }
-    else if( !keep.b_bool )
-    {
-        while( ( p_sout = vlc_object_find( p_parent, VLC_OBJECT_SOUT,
-                                           FIND_PARENT ) ) != NULL )
-        {
-            msg_Dbg( p_parent, "sout keep: destroying old sout" );
-            vlc_object_release( p_sout );
-            sout_DeleteInstance( p_sout );
-        }
-    }
 
     /* *** Allocate descriptor *** */
     p_sout = vlc_object_create( p_parent, VLC_OBJECT_SOUT );
@@ -142,8 +103,11 @@ sout_instance_t *__sout_NewInstance( vlc_object_t *p_parent, char * psz_dest )
     /* attach it for inherit */
     vlc_object_attach( p_sout, p_parent );
 
-    p_sout->p_stream = sout_StreamNew( p_sout, p_sout->psz_chain );
+    /* */
+    var_Create( p_sout, "sout-mux-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
 
+    /* */
+    p_sout->p_stream = sout_StreamNew( p_sout, p_sout->psz_chain );
     if( p_sout->p_stream == NULL )
     {
         msg_Err( p_sout, "stream chain failed for `%s'", p_sout->psz_chain );
@@ -164,9 +128,6 @@ sout_instance_t *__sout_NewInstance( vlc_object_t *p_parent, char * psz_dest )
  *****************************************************************************/
 void sout_DeleteInstance( sout_instance_t * p_sout )
 {
-    /* Unlink object */
-    vlc_object_detach( p_sout );
-
     /* remove the stream out chain */
     sout_StreamDelete( p_sout->p_stream );
 
@@ -275,7 +236,7 @@ int sout_InputSendBuffer( sout_packetizer_input_t *p_input,
  * sout_AccessOutNew: allocate a new access out
  *****************************************************************************/
 sout_access_out_t *sout_AccessOutNew( sout_instance_t *p_sout,
-                                      char *psz_access, char *psz_name )
+                                      const char *psz_access, const char *psz_name )
 {
     sout_access_out_t *p_access;
     char              *psz_next;
@@ -293,12 +254,13 @@ sout_access_out_t *sout_AccessOutNew( sout_instance_t *p_sout,
     {
         free( psz_next );
     }
-    p_access->psz_name   = strdup( psz_name ? psz_name : "" );
+    p_access->psz_path   = strdup( psz_name ? psz_name : "" );
     p_access->p_sout     = p_sout;
     p_access->p_sys = NULL;
     p_access->pf_seek    = NULL;
     p_access->pf_read    = NULL;
     p_access->pf_write   = NULL;
+    p_access->pf_control = NULL;
     p_access->p_module   = NULL;
 
     p_access->i_writes = 0;
@@ -312,7 +274,7 @@ sout_access_out_t *sout_AccessOutNew( sout_instance_t *p_sout,
     if( !p_access->p_module )
     {
         free( p_access->psz_access );
-        free( p_access->psz_name );
+        free( p_access->psz_path );
         vlc_object_detach( p_access );
         vlc_object_destroy( p_access );
         return( NULL );
@@ -334,7 +296,7 @@ void sout_AccessOutDelete( sout_access_out_t *p_access )
 
     config_ChainDestroy( p_access->p_cfg );
 
-    free( p_access->psz_name );
+    free( p_access->psz_path );
 
     vlc_object_destroy( p_access );
 }
@@ -373,11 +335,11 @@ int sout_AccessOutWrite( sout_access_out_t *p_access, block_t *p_buffer )
         if( p_input )
         {
             stats_UpdateInteger( p_input, p_input->p->counters.p_sout_sent_packets,
-                                30, NULL );
+                     30, NULL );
             stats_UpdateInteger( p_input, p_input->p->counters.p_sout_sent_bytes,
                                  p_access->i_sent_bytes, &i_total );
             stats_UpdateFloat( p_input, p_input->p->counters.p_sout_send_bitrate,
-                                (float)i_total, NULL );
+                    (float)i_total, NULL );
             p_access->i_sent_bytes = 0;
             vlc_object_release( p_input );
         }
@@ -385,6 +347,15 @@ int sout_AccessOutWrite( sout_access_out_t *p_access, block_t *p_buffer )
     return p_access->pf_write( p_access, p_buffer );
 }
 
+/**
+ * sout_AccessOutControl
+ */
+int sout_AccessOutControl (sout_access_out_t *access, int query, va_list args)
+{
+    return (access->pf_control) ? access->pf_control (access, query, args)
+                                : VLC_EGENERIC;
+}
+
 /*****************************************************************************
  * sout_MuxNew: create a new mux
  *****************************************************************************/
@@ -502,7 +473,7 @@ sout_input_t *sout_MuxAddStream( sout_mux_t *p_mux, es_format_t *p_fmt )
     if( !p_mux->b_add_stream_any_time && !p_mux->b_waiting_stream )
     {
         msg_Err( p_mux, "cannot add a new stream (unsupported while muxing "
-                        "to this format)" );
+                        "to this format). You can try increasing sout-mux-caching value" );
         return NULL;
     }
 
@@ -535,7 +506,8 @@ void sout_MuxDeleteStream( sout_mux_t *p_mux, sout_input_t *p_input )
 {
     int i_index;
 
-    if( p_mux->b_waiting_stream && p_input->p_fifo->i_depth > 0 )
+    if( p_mux->b_waiting_stream
+     && block_FifoCount( p_input->p_fifo ) > 0 )
     {
         /* We stop waiting, and call the muxer for taking care of the data
          * before we remove this es */
@@ -582,22 +554,16 @@ void sout_MuxSendBuffer( sout_mux_t *p_mux, sout_input_t *p_input,
 
     if( p_mux->b_waiting_stream )
     {
+        const int64_t i_caching = var_GetInteger( p_mux->p_sout, "sout-mux-caching" ) * I64C(1000);
+
         if( p_mux->i_add_stream_start < 0 )
-        {
             p_mux->i_add_stream_start = p_buffer->i_dts;
-        }
 
-        if( p_mux->i_add_stream_start >= 0 &&
-            p_mux->i_add_stream_start + I64C(1500000) < p_buffer->i_dts )
-        {
-            /* Wait until we have more than 1.5 seconds worth of data
-             * before start muxing */
-            p_mux->b_waiting_stream = VLC_FALSE;
-        }
-        else
-        {
+        /* Wait until we have enought data before muxing */
+        if( p_mux->i_add_stream_start < 0 ||
+            p_buffer->i_dts < p_mux->i_add_stream_start + i_caching )
             return;
-        }
+        p_mux->b_waiting_stream = VLC_FALSE;
     }
     p_mux->pf_mux( p_mux );
 }
@@ -609,8 +575,8 @@ static int mrl_Parse( mrl_t *p_mrl, const char *psz_mrl )
 {
     char * psz_dup = strdup( psz_mrl );
     char * psz_parser = psz_dup;
-    char * psz_access;
-    char * psz_way;
+    const char * psz_access;
+    const char * psz_way;
     char * psz_name;
 
     /* *** first parse psz_dest */