]> git.sesse.net Git - vlc/blobdiff - modules/stream_out/transcode.c
check for malloc return value
[vlc] / modules / stream_out / transcode.c
index 7c7b38fdfe33f4bbb9eda175c15559187e4e4109..ab067af54f2a7a704c3d7772125bde480b0080be 100644 (file)
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include <vlc/vlc.h>
 #include <vlc_input.h>
 #include <vlc_sout.h>
@@ -263,7 +267,7 @@ vlc_module_begin();
                  ARATE_LONGTEXT, VLC_TRUE );
     add_bool( SOUT_CFG_PREFIX "audio-sync", 0, NULL, ASYNC_TEXT,
               ASYNC_LONGTEXT, VLC_FALSE );
-    add_module_list_cat( SOUT_CFG_PREFIX "afilter", SUBCAT_AUDIO_MISC,
+    add_module_list( SOUT_CFG_PREFIX "afilter",  "audio filter2",
                      NULL, NULL,
                      AFILTER_TEXT, AFILTER_LONGTEXT, VLC_FALSE );
 
@@ -274,7 +278,7 @@ vlc_module_begin();
                 SCODEC_LONGTEXT, VLC_FALSE );
     add_bool( SOUT_CFG_PREFIX "soverlay", 0, NULL, SCODEC_TEXT,
                SCODEC_LONGTEXT, VLC_FALSE );
-    add_module_list_cat( SOUT_CFG_PREFIX "sfilter", SUBCAT_VIDEO_SUBPIC,
+    add_module_list( SOUT_CFG_PREFIX "sfilter", "video filter",
                      NULL, NULL,
                      SFILTER_TEXT, SFILTER_LONGTEXT, VLC_FALSE );
 
@@ -309,7 +313,7 @@ static int               Del ( sout_stream_t *, sout_stream_id_t * );
 static int               Send( sout_stream_t *, sout_stream_id_t *, block_t* );
 
 static int  transcode_audio_new    ( sout_stream_t *, sout_stream_id_t * );
-static void transcode_audio_close  ( sout_stream_t *, sout_stream_id_t * );
+static void transcode_audio_close  ( sout_stream_id_t * );
 static int  transcode_audio_process( sout_stream_t *, sout_stream_id_t *,
                                      block_t *, block_t ** );
 
@@ -331,7 +335,7 @@ static picture_t *video_new_buffer_filter( filter_t * );
 static void video_del_buffer_filter( filter_t *, picture_t * );
 
 static int  transcode_spu_new    ( sout_stream_t *, sout_stream_id_t * );
-static void transcode_spu_close  ( sout_stream_t *, sout_stream_id_t * );
+static void transcode_spu_close  ( sout_stream_id_t * );
 static int  transcode_spu_process( sout_stream_t *, sout_stream_id_t *,
                                    block_t *, block_t ** );
 
@@ -373,8 +377,8 @@ struct sout_stream_sys_t
     vlc_fourcc_t    i_acodec;   /* codec audio (0 if not transcode) */
     char            *psz_aenc;
     config_chain_t  *p_audio_cfg;
-    int             i_sample_rate;
-    int             i_channels;
+    uint32_t        i_sample_rate;
+    uint32_t        i_channels;
     int             i_abitrate;
     char            *psz_afilters[TRANSCODE_FILTERS];
     config_chain_t  *p_afilters_cfg[TRANSCODE_FILTERS];
@@ -468,7 +472,7 @@ static int Open( vlc_object_t *p_this )
     if( !p_sys->p_out )
     {
         msg_Err( p_stream, "cannot create chain" );
-        vlc_object_destroy( p_sys );
+        vlc_object_release( p_sys );
         return VLC_EGENERIC;
     }
 
@@ -880,7 +884,7 @@ static void Close( vlc_object_t * p_this )
     }
     if( p_sys->psz_osdenc ) free( p_sys->psz_osdenc );
 
-    vlc_object_destroy( p_sys );
+    vlc_object_release( p_sys );
 }
 
 struct sout_stream_id_t
@@ -962,7 +966,7 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
         /* Complete destination format */
         id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
         id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
-            p_sys->i_sample_rate : (int)p_fmt->audio.i_rate;
+            p_sys->i_sample_rate : p_fmt->audio.i_rate;
         id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
         id->p_encoder->fmt_out.audio.i_bitspersample =
             p_fmt->audio.i_bitspersample;
@@ -999,7 +1003,7 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
 
         if( !id->id )
         {
-            transcode_audio_close( p_stream, id );
+            transcode_audio_close( id );
             goto error;
         }
 
@@ -1059,7 +1063,7 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
 
         if( !id->id )
         {
-            transcode_spu_close( p_stream, id );
+            transcode_spu_close( id );
             goto error;
         }
     }
@@ -1109,7 +1113,7 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
     if( id->p_decoder )
     {
         vlc_object_detach( id->p_decoder );
-        vlc_object_destroy( id->p_decoder );
+        vlc_object_release( id->p_decoder );
         id->p_decoder = NULL;
     }
 
@@ -1117,7 +1121,7 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
     {
         vlc_object_detach( id->p_encoder );
         es_format_Clean( &id->p_encoder->fmt_out );
-        vlc_object_destroy( id->p_encoder );
+        vlc_object_release( id->p_encoder );
         id->p_encoder = NULL;
     }
 
@@ -1134,7 +1138,7 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
         switch( id->p_decoder->fmt_in.i_cat )
         {
         case AUDIO_ES:
-            transcode_audio_close( p_stream, id );
+            transcode_audio_close( id );
             break;
         case VIDEO_ES:
             transcode_video_close( p_stream, id );
@@ -1143,7 +1147,7 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
             if( p_sys->b_osd )
                 transcode_osd_close( p_stream, id );
             else
-                transcode_spu_close( p_stream, id );
+                transcode_spu_close( id );
             break;
         }
     }
@@ -1153,7 +1157,7 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
     if( id->p_decoder )
     {
         vlc_object_detach( id->p_decoder );
-        vlc_object_destroy( id->p_decoder );
+        vlc_object_release( id->p_decoder );
         id->p_decoder = NULL;
     }
 
@@ -1161,7 +1165,7 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
     {
         vlc_object_detach( id->p_encoder );
         es_format_Clean( &id->p_encoder->fmt_out );
-        vlc_object_destroy( id->p_encoder );
+        vlc_object_release( id->p_encoder );
         id->p_encoder = NULL;
     }
     free( id );
@@ -1264,6 +1268,11 @@ static int audio_BitsPerSample( vlc_fourcc_t i_format )
     return 0;
 }
 
+static block_t *transcode_audio_alloc (filter_t *filter, int size)
+{
+    return block_New (filter, size);
+}
+
 static filter_t *transcode_audio_filter_new( sout_stream_t *p_stream,
                                              sout_stream_id_t *id,
                                              es_format_t *p_fmt_in,
@@ -1274,7 +1283,7 @@ static filter_t *transcode_audio_filter_new( sout_stream_t *p_stream,
     filter_t *p_filter = vlc_object_create( p_stream, VLC_OBJECT_FILTER );
 
     vlc_object_attach( p_filter, p_stream );
-    p_filter->pf_audio_buffer_new = (block_t* (*) (filter_t*, int))__block_New;
+    p_filter->pf_audio_buffer_new = transcode_audio_alloc;
 
     p_filter->fmt_in = *p_fmt_in;
     p_filter->fmt_out = *p_fmt_out;
@@ -1292,7 +1301,7 @@ static filter_t *transcode_audio_filter_new( sout_stream_t *p_stream,
     else
     {
         vlc_object_detach( p_filter );
-        vlc_object_destroy( p_filter );
+        vlc_object_release( p_filter );
         p_filter = 0;
     }
 
@@ -1344,11 +1353,11 @@ static int transcode_audio_new( sout_stream_t *p_stream,
                     id->p_decoder->fmt_out.i_codec );
     id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec;
 
-    /* Initialization of encoder format structures */
-    es_format_Init( &id->p_encoder->fmt_in, AUDIO_ES, VLC_FOURCC('f','l','3','2') );
-    id->p_encoder->fmt_in.audio.i_format = VLC_FOURCC('f','l','3','2');
-
-    id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
+    if( ( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('s','a','m','r') ) ||
+        ( id->p_encoder->fmt_out.i_codec == VLC_FOURCC('s','a','w','b') ) )
+         id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate;
+    else
+        id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
     id->p_encoder->fmt_in.audio.i_physical_channels =
         id->p_encoder->fmt_out.audio.i_physical_channels;
     id->p_encoder->fmt_in.audio.i_original_channels =
@@ -1372,15 +1381,6 @@ static int transcode_audio_new( sout_stream_t *p_stream,
     id->p_encoder->fmt_in.audio.i_bitspersample =
         audio_BitsPerSample( id->p_encoder->fmt_in.i_codec );
 
-    /* Fix AAC SBR changing number of channels and sampling rate */
-    if( id->p_decoder->fmt_in.i_codec == VLC_FOURCC('m','p','4','a') &&
-        fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
-        fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels )
-    {
-      id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
-      id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
-    }
-
     /* Load conversion filters */
     if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ||
         fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate )
@@ -1419,7 +1419,7 @@ static int transcode_audio_new( sout_stream_t *p_stream,
         msg_Err( p_stream, "no audio filter found (%4.4s->%4.4s)",
                  (char *)&fmt_last.i_codec,
                  (char *)&id->p_encoder->fmt_in.i_codec );
-        transcode_audio_close( p_stream, id );
+        transcode_audio_close( id );
         return VLC_EGENERIC;
     }
 
@@ -1467,7 +1467,7 @@ static int transcode_audio_new( sout_stream_t *p_stream,
         if( !id->p_encoder->p_module )
         {
             msg_Err( p_stream, "cannot find encoder (%s)", p_sys->psz_aenc );
-            transcode_audio_close( p_stream, id );
+            transcode_audio_close( id );
             return VLC_EGENERIC;
         }
         id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec;
@@ -1478,7 +1478,7 @@ static int transcode_audio_new( sout_stream_t *p_stream,
                  " %i to %i channels", fmt_last.audio.i_channels,
                  id->p_encoder->fmt_in.audio.i_channels );
 
-        transcode_audio_close( p_stream, id );
+        transcode_audio_close( id );
         return VLC_EGENERIC;
 #endif
     }
@@ -1493,7 +1493,7 @@ static int transcode_audio_new( sout_stream_t *p_stream,
         id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate;
         id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;
 #else
-        transcode_audio_close( p_stream, id );
+        transcode_audio_close( id );
         return VLC_EGENERIC;
 #endif
     }
@@ -1505,8 +1505,7 @@ static int transcode_audio_new( sout_stream_t *p_stream,
     return VLC_SUCCESS;
 }
 
-static void transcode_audio_close( sout_stream_t *p_stream,
-                                   sout_stream_id_t *id )
+static void transcode_audio_close( sout_stream_id_t *id )
 {
     int i;
 
@@ -1526,14 +1525,14 @@ static void transcode_audio_close( sout_stream_t *p_stream,
         vlc_object_detach( id->pp_filter[i] );
         if( id->pp_filter[i]->p_module )
             module_Unneed( id->pp_filter[i], id->pp_filter[i]->p_module );
-        vlc_object_destroy( id->pp_filter[i] );
+        vlc_object_release( id->pp_filter[i] );
     }
     for( i = 0; i < id->i_ufilter; i++ )
     {
         vlc_object_detach( id->pp_ufilter[i] );
         if( id->pp_ufilter[i]->p_module )
             module_Unneed( id->pp_ufilter[i], id->pp_ufilter[i]->p_module );
-        vlc_object_destroy( id->pp_ufilter[i] );
+        vlc_object_release( id->pp_ufilter[i] );
     }
 }
 
@@ -1650,8 +1649,9 @@ static aout_buffer_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
 
 static void audio_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
 {
+    VLC_UNUSED(p_dec);
     if( p_buffer && p_buffer->p_sys ) block_Release( p_buffer->p_sys );
-    if( p_buffer ) free( p_buffer );
+    free( p_buffer );
 }
 
 /*
@@ -2110,7 +2110,7 @@ static void transcode_video_close( sout_stream_t *p_stream,
                                   id->pp_filter[i]->p_owner->pp_pics[j] );
         }
         free( id->pp_filter[i]->p_owner );
-        vlc_object_destroy( id->pp_filter[i] );
+        vlc_object_release( id->pp_filter[i] );
         id->pp_filter[i] = NULL;
     }
 
@@ -2128,7 +2128,7 @@ static void transcode_video_close( sout_stream_t *p_stream,
                                   id->pp_ufilter[i]->p_owner->pp_pics[j] );
         }
         free( id->pp_ufilter[i]->p_owner );
-        vlc_object_destroy( id->pp_ufilter[i] );
+        vlc_object_release( id->pp_ufilter[i] );
         id->pp_ufilter[i] = NULL;
     }
 }
@@ -2242,7 +2242,7 @@ static int transcode_video_process( sout_stream_t *p_stream,
                 {
                     msg_Dbg( p_stream, "no video filter found" );
                     vlc_object_detach( id->pp_filter[id->i_filter] );
-                    vlc_object_destroy( id->pp_filter[id->i_filter] );
+                    vlc_object_release( id->pp_filter[id->i_filter] );
                 }
             }
 
@@ -2283,7 +2283,11 @@ static int transcode_video_process( sout_stream_t *p_stream,
 
                 id->pp_filter[id->i_filter]->p_module =
                     module_Need( id->pp_filter[id->i_filter],
+#if ( (defined(HAVE_FFMPEG_SWSCALE_H) || defined(HAVE_LIBSWSCALE_TREE)) )
+                                 "video filter2", "scale", VLC_TRUE );
+#else
                                  "crop padd", 0, 0 );
+#endif
                 if( id->pp_filter[id->i_filter]->p_module )
                 {
                     id->pp_filter[id->i_filter]->p_owner =
@@ -2298,7 +2302,7 @@ static int transcode_video_process( sout_stream_t *p_stream,
                 {
                     msg_Dbg( p_stream, "no video filter found" );
                     vlc_object_detach( id->pp_filter[id->i_filter] );
-                    vlc_object_destroy( id->pp_filter[id->i_filter] );
+                    vlc_object_release( id->pp_filter[id->i_filter] );
 
                     p_pic->pf_release( p_pic );
                     transcode_video_close( p_stream, id );
@@ -2337,7 +2341,7 @@ static int transcode_video_process( sout_stream_t *p_stream,
                 {
                     msg_Dbg( p_stream, "no video filter found" );
                     vlc_object_detach( id->pp_ufilter[id->i_ufilter] );
-                    vlc_object_destroy( id->pp_ufilter[id->i_ufilter] );
+                    vlc_object_release( id->pp_ufilter[id->i_ufilter] );
                     id->pp_ufilter[id->i_ufilter] = NULL;
                 }
             }
@@ -2643,30 +2647,38 @@ static picture_t *video_new_buffer_filter( filter_t *p_filter )
 
 static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic )
 {
-    if( p_pic && p_pic->p_data_orig ) free( p_pic->p_data_orig );
-    if( p_pic && p_pic->p_sys ) free( p_pic->p_sys );
-    if( p_pic ) free( p_pic );
+    VLC_UNUSED(p_this);
+    if( p_pic )
+    {
+        free( p_pic->p_data_orig );
+        free( p_pic->p_sys );
+        free( p_pic );
+    }
 }
 
 static void video_del_buffer_decoder( decoder_t *p_decoder, picture_t *p_pic )
 {
+    VLC_UNUSED(p_decoder);
     p_pic->i_refcount = 0;
     p_pic->i_status = DESTROYED_PICTURE;
 }
 
 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
 {
+    VLC_UNUSED(p_filter);
     p_pic->i_refcount = 0;
     p_pic->i_status = DESTROYED_PICTURE;
 }
 
 static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
 {
+    VLC_UNUSED(p_dec);
     p_pic->i_refcount++;
 }
 
 static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
 {
+    VLC_UNUSED(p_dec);
     video_release_buffer( p_pic );
 }
 
@@ -2729,7 +2741,7 @@ static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
     return VLC_SUCCESS;
 }
 
-static void transcode_spu_close( sout_stream_t *p_stream, sout_stream_id_t *id)
+static void transcode_spu_close( sout_stream_id_t *id)
 {
     /* Close decoder */
     if( id->p_decoder->p_module )