]> git.sesse.net Git - vlc/blobdiff - modules/stream_out/transcode.c
* Add the hdv2 fourcc which is simply HD MPEG2
[vlc] / modules / stream_out / transcode.c
index fcb4eaf7bd01a811d26c3b11f3a6e03ae475356c..e7ee6e53c369749742875eac84f4f42f98935f6d 100644 (file)
@@ -36,7 +36,7 @@
 #include <vlc/vout.h>
 #include <vlc/decoder.h>
 #include "vlc_filter.h"
-#include "osd.h"
+#include "vlc_osd.h"
 
 #define MASTER_SYNC_MAX_DRIFT 100000
 
 #define HEIGHT_TEXT N_("Video height")
 #define HEIGHT_LONGTEXT N_( \
     "Allows you to specify the output video height." )
+#define MAXWIDTH_TEXT N_("Maximum video width")
+#define MAXWIDTH_LONGTEXT N_( \
+    "Allows you to specify a maximum output video width." )
+#define MAXHEIGHT_TEXT N_("Maximum video height")
+#define MAXHEIGHT_LONGTEXT N_( \
+    "Allows you to specify a maximum output video height." )
 #define VFILTER_TEXT N_("Video filter")
 #define VFILTER_LONGTEXT N_( \
     "Allows you to specify video filters used after the video " \
     "transcoding. The subpictures produced by the filters will be overlayed " \
     "directly onto the video." )
 
+#define OSD_TEXT N_("OSD menu")
+#define OSD_LONGTEXT N_(\
+    "Enable streaming of the On Screen Display. It uses the osdmenu subfilter." )
+                  
 #define THREADS_TEXT N_("Number of threads")
 #define THREADS_LONGTEXT N_( \
     "Allows you to specify the number of threads used for the transcoding." )
@@ -184,6 +194,10 @@ vlc_module_begin();
                  WIDTH_LONGTEXT, VLC_TRUE );
     add_integer( SOUT_CFG_PREFIX "height", 0, NULL, HEIGHT_TEXT,
                  HEIGHT_LONGTEXT, VLC_TRUE );
+    add_integer( SOUT_CFG_PREFIX "maxwidth", 0, NULL, MAXWIDTH_TEXT,
+                 MAXWIDTH_LONGTEXT, VLC_TRUE );
+    add_integer( SOUT_CFG_PREFIX "maxheight", 0, NULL, MAXHEIGHT_TEXT,
+                 MAXHEIGHT_LONGTEXT, VLC_TRUE );
     add_module_list_cat( SOUT_CFG_PREFIX "vfilter", SUBCAT_VIDEO_VFILTER,
                      NULL, NULL,
                      VFILTER_TEXT, VFILTER_LONGTEXT, VLC_FALSE );
@@ -222,6 +236,10 @@ vlc_module_begin();
                      NULL, NULL,
                      SFILTER_TEXT, SFILTER_LONGTEXT, VLC_FALSE );
 
+    set_section( N_("On Screen Display"), NULL );
+    add_bool( SOUT_CFG_PREFIX "osd", 0, NULL, OSD_TEXT,
+              OSD_LONGTEXT, VLC_FALSE );
+    
     set_section( N_("Miscellaneous"), NULL );
     add_integer( SOUT_CFG_PREFIX "threads", 0, NULL, THREADS_TEXT,
                  THREADS_LONGTEXT, VLC_TRUE );
@@ -235,7 +253,7 @@ static const char *ppsz_sout_options[] = {
     "scale", "fps", "width", "height", "vfilter", "deinterlace",
     "deinterlace-module", "threads", "hurry-up", "aenc", "acodec", "ab",
     "samplerate", "channels", "senc", "scodec", "soverlay", "sfilter",
-    "audio-sync", "high-priority", NULL
+    "osd", "audio-sync", "high-priority", "maxwidth", "maxheight", NULL
 };
 
 /*****************************************************************************
@@ -320,8 +338,8 @@ struct sout_stream_sys_t
     int             i_vbitrate;
     double          f_scale;
     double          f_fps;
-    int             i_width;
-    int             i_height;
+    unsigned int    i_width, i_maxwidth;
+    unsigned int    i_height, i_maxheight;
     vlc_bool_t      b_deinterlace;
     char            *psz_deinterlace;
     sout_cfg_t      *p_deinterlace_cfg;
@@ -349,8 +367,9 @@ struct sout_stream_sys_t
     vlc_fourcc_t    i_osdcodec; /* codec osd menu (0 if not transcode) */
     char            *psz_osdenc;
     sout_cfg_t      *p_osd_cfg;
-    vlc_bool_t      b_osd;      /* VLC_TRUE when osd es is registered */
-    
+    vlc_bool_t      b_es_osd;      /* VLC_TRUE when osd es is registered */
+    vlc_bool_t      b_sout_osd;
+        
     /* Sync */
     vlc_bool_t      b_master_sync;
     mtime_t         i_master_drift;
@@ -480,6 +499,12 @@ static int Open( vlc_object_t *p_this )
     var_Get( p_stream, SOUT_CFG_PREFIX "height", &val );
     p_sys->i_height = val.i_int;
 
+    var_Get( p_stream, SOUT_CFG_PREFIX "maxwidth", &val );
+    p_sys->i_maxwidth = val.i_int;
+
+    var_Get( p_stream, SOUT_CFG_PREFIX "maxheight", &val );
+    p_sys->i_maxheight = val.i_int;
+
     var_Get( p_stream, SOUT_CFG_PREFIX "vfilter", &val );
     p_sys->i_vfilters = 0;
     if( val.psz_string && *val.psz_string )
@@ -584,10 +609,13 @@ static int Open( vlc_object_t *p_this )
     p_sys->psz_osdenc = NULL;
     p_sys->p_osd_cfg  = NULL;
     p_sys->i_osdcodec = 0;
-    p_sys->b_osd      = VLC_FALSE;
-    if( config_GetInt( p_stream, "osd" ) )
+    p_sys->b_es_osd   = VLC_FALSE;
+
+    var_Get( p_stream, SOUT_CFG_PREFIX "osd", &val );
+    p_sys->b_sout_osd = val.b_bool;
+    if( p_sys->b_sout_osd )
     {
-/*        vlc_value_t val;*/
+        vlc_value_t osd_val;
         char *psz_next;
        
         psz_next = sout_CfgCreate( &p_sys->psz_osdenc,
@@ -598,15 +626,21 @@ static int Open( vlc_object_t *p_this )
 
         msg_Dbg( p_stream, "codec osd=%4.4s", (char *)&p_sys->i_osdcodec );
 
-/*        val.psz_string = strdup("osdmenu");
         if( !p_sys->p_spu )
         {
+            osd_val.psz_string = strdup("osdmenu");
             p_sys->p_spu = spu_Create( p_stream );
             var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING );
+            var_Set( p_sys->p_spu, "sub-filter", osd_val );
             spu_Init( p_sys->p_spu );
-        }            
-        var_Set( p_sys->p_spu, "sub-filter", val );        
-        if( val.psz_string ) free( val.psz_string );*/
+            if( osd_val.psz_string ) free( osd_val.psz_string );
+        }
+        else
+        {
+            osd_val.psz_string = strdup("osdmenu");
+            var_Set( p_sys->p_spu, "sub-filter", osd_val );
+            if( osd_val.psz_string ) free( osd_val.psz_string );
+        }         
     }
 
     /* Audio settings */
@@ -896,17 +930,17 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
         if( !id->id ) goto error;
     }
 
-    if( config_GetInt( p_stream, "osd" ) )
+    if( p_sys->b_sout_osd )
     {
         /* Create a fake OSD menu elementary stream */
-        if( !p_sys->b_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
+        if( !p_sys->b_es_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
         {
             if( transcode_osd_new( p_stream, p_sys->id_osd ) )
             {
                 msg_Err( p_stream, "cannot create osd chain" );
                 goto error;
             }
-            p_sys->b_osd = VLC_TRUE;
+            p_sys->b_es_osd = VLC_TRUE;
         }
     }
     return id;
@@ -932,7 +966,7 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
 {
     sout_stream_sys_t *p_sys = p_stream->p_sys;
 
-    if( config_GetInt( p_stream, "osd" ) && p_sys->b_osd )
+    if( p_sys->b_es_osd )
         transcode_osd_close( p_stream, p_sys->id_osd );
 
     if( id->b_transcode )
@@ -979,7 +1013,7 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
     if( !id->b_transcode && id->id )
     {
         /* Transcode OSD menu pictures. */
-        if( p_sys->b_osd )
+        if( p_sys->b_es_osd )
         {
             transcode_osd_process( p_stream, id, p_buffer, &p_out );                
         }
@@ -1516,6 +1550,13 @@ static int transcode_video_encoder_open( sout_stream_t *p_stream,
             id->p_encoder->fmt_out.video.i_height / (double)i_height * i_width;
     }
 
+    if( p_sys->i_maxwidth
+         && id->p_encoder->fmt_out.video.i_width > p_sys->i_maxwidth )
+        id->p_encoder->fmt_out.video.i_width = p_sys->i_maxwidth;
+    if( p_sys->i_maxheight
+         && id->p_encoder->fmt_out.video.i_height > p_sys->i_maxheight )
+        id->p_encoder->fmt_out.video.i_height = p_sys->i_maxheight;
+
     /* Make sure the size is at least a multiple of 2 */
     id->p_encoder->fmt_out.video.i_width =
         (id->p_encoder->fmt_out.video.i_width + 1) >> 1 << 1;
@@ -1671,7 +1712,7 @@ static int transcode_video_process( sout_stream_t *p_stream,
 {
     sout_stream_sys_t *p_sys = p_stream->p_sys;
     int i_duplicate = 1, i;
-    picture_t *p_pic;
+    picture_t *p_pic, *p_pic2 = NULL;
     *out = NULL;
 
     while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
@@ -1919,17 +1960,7 @@ static int transcode_video_process( sout_stream_t *p_stream,
             p_pic = id->pp_vfilter[i]->pf_video_filter(id->pp_vfilter[i], p_pic);
         }
 
-        if( p_sys->i_threads >= 1 )
-        {
-            vlc_mutex_lock( &p_sys->lock_out );
-            p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
-            p_sys->i_last_pic %= PICTURE_RING_SIZE;
-            *out = p_sys->p_buffers;
-            p_sys->p_buffers = NULL;
-            vlc_cond_signal( &p_sys->cond );
-            vlc_mutex_unlock( &p_sys->lock_out );
-        }
-        else
+        if( p_sys->i_threads == 0 )
         {
             block_t *p_block;
             p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );
@@ -1964,17 +1995,11 @@ static int transcode_video_process( sout_stream_t *p_stream,
             if( p_sys->i_threads >= 1 )
             {
                 /* We can't modify the picture, we need to duplicate it */
-                picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );
-                if( p_tmp != NULL )
+                p_pic2 = video_new_buffer_decoder( id->p_decoder );
+                if( p_pic2 != NULL )
                 {
-                    vout_CopyPicture( p_stream, p_tmp, p_pic );
-                    p_pic = p_tmp;
-
-                    vlc_mutex_lock( &p_sys->lock_out );
-                    p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
-                    p_sys->i_last_pic %= PICTURE_RING_SIZE;
-                    vlc_cond_signal( &p_sys->cond );
-                    vlc_mutex_unlock( &p_sys->lock_out );
+                    vout_CopyPicture( p_stream, p_pic2, p_pic );
+                    p_pic2->date = i_pts;
                 }
             }
             else
@@ -1987,7 +2012,25 @@ static int transcode_video_process( sout_stream_t *p_stream,
         }
 
         if( p_sys->i_threads == 0 )
+        {
             p_pic->pf_release( p_pic );
+        }
+        else
+        {
+            vlc_mutex_lock( &p_sys->lock_out );
+            p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;
+            p_sys->i_last_pic %= PICTURE_RING_SIZE;
+            *out = p_sys->p_buffers;
+            p_sys->p_buffers = NULL;
+            if( p_pic2 != NULL )
+            {
+                p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2;
+                p_sys->i_last_pic %= PICTURE_RING_SIZE;
+            }
+            vlc_cond_signal( &p_sys->cond );
+            vlc_mutex_unlock( &p_sys->lock_out );
+        }
+
     }
 
     return VLC_SUCCESS;
@@ -2384,7 +2427,7 @@ static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
     }
 
     p_sys->id_osd = id;
-    p_sys->b_osd = VLC_TRUE;
+    p_sys->b_es_osd = VLC_TRUE;
 
     if( !p_sys->p_spu )
     {
@@ -2410,7 +2453,7 @@ static int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
     if( fmt.psz_language ) free( fmt.psz_language );
     if( id ) free( id );
     p_sys->id_osd = NULL;
-    p_sys->b_osd = VLC_FALSE;
+    p_sys->b_es_osd = VLC_FALSE;
     return VLC_EGENERIC;
 }
     
@@ -2419,7 +2462,7 @@ static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
     sout_stream_sys_t *p_sys = p_stream->p_sys;
     
     /* Close encoder */
-    if( p_sys->b_osd && id )
+    if( p_sys->b_es_osd && id )
     {
         if( id->p_encoder->p_module )
             module_Unneed( id->p_encoder, id->p_encoder->p_module );
@@ -2432,7 +2475,7 @@ static void transcode_osd_close( sout_stream_t *p_stream, sout_stream_id_t *id)
             vlc_object_destroy( id->p_encoder );
         }
     }
-    p_sys->b_osd = VLC_FALSE;
+    p_sys->b_es_osd = VLC_FALSE;
     if( id ) free( id );
 }