]> git.sesse.net Git - vlc/blobdiff - modules/stream_out/transcode.c
* modules/gui/wxwindows/*: misc fixes.
[vlc] / modules / stream_out / transcode.c
index 3c4d572b1c67ca7216332ec57ac0ccbee4c671a8..c611dd8459290cf7c170f008749d167904bce2f0 100644 (file)
@@ -2,7 +2,7 @@
  * transcode.c
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: transcode.c,v 1.7 2003/05/02 14:51:57 fenrir Exp $
+ * $Id: transcode.c,v 1.15 2003/05/04 18:51:34 fenrir Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -77,8 +77,13 @@ struct sout_stream_sys_t
 
     vlc_fourcc_t    i_vcodec;   /*    "   video  " "   "      " */
     int             i_vbitrate;
+    int             i_vtolerance;
     int             i_width;
     int             i_height;
+    int             i_key_int;
+    int             i_qmin;
+    int             i_qmax;
+    vlc_bool_t      b_hq;
     vlc_bool_t      b_deinterlace;
 
     int             i_crop_top;
@@ -106,8 +111,13 @@ static int Open( vlc_object_t *p_this )
 
     p_sys->i_vcodec     = 0;
     p_sys->i_vbitrate   = 0;
+    p_sys->i_vtolerance = -1;
     p_sys->i_width      = 0;
     p_sys->i_height     = 0;
+    p_sys->i_key_int    = -1;
+    p_sys->i_qmin       = 2;
+    p_sys->i_qmax       = 31;
+    p_sys->b_hq         = VLC_FALSE;
     p_sys->b_deinterlace= VLC_FALSE;
 
     p_sys->i_crop_top   = 0;
@@ -135,6 +145,10 @@ static int Open( vlc_object_t *p_this )
         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "ab" ) ) )
         {
             p_sys->i_abitrate = atoi( val );
+            if( p_sys->i_abitrate < 4000 )
+            {
+                p_sys->i_abitrate *= 1000;
+            }
         }
 
         msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s",
@@ -163,6 +177,14 @@ static int Open( vlc_object_t *p_this )
         if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vb" ) ) )
         {
             p_sys->i_vbitrate = atoi( val );
+            if( p_sys->i_vbitrate < 16000 )
+            {
+                p_sys->i_vbitrate *= 1000;
+            }
+        }
+        if( ( val = sout_cfg_find_value( p_stream->p_cfg, "vt" ) ) )
+        {
+            p_sys->i_vtolerance = atoi( val );
         }
         if( sout_cfg_find( p_stream->p_cfg, "deinterlace" ) )
         {
@@ -185,6 +207,22 @@ static int Open( vlc_object_t *p_this )
         {
             p_sys->i_crop_right = atoi( val );
         }
+        if( ( val = sout_cfg_find_value( p_stream->p_cfg, "keyint" ) ) )
+        {
+            p_sys->i_key_int    = atoi( val );
+        }
+        if( sout_cfg_find( p_stream->p_cfg, "hq" ) )
+        {
+            p_sys->b_hq = VLC_TRUE;
+        }
+        if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmin" ) ) )
+        {
+            p_sys->i_qmin   = atoi( val );
+        }
+        if( ( val = sout_cfg_find_value( p_stream->p_cfg, "qmax" ) ) )
+        {
+            p_sys->i_qmax   = atoi( val );
+        }
 
         msg_Dbg( p_stream, "codec video=%4.4s %dx%d %dkb/s",
                  fcc,
@@ -585,7 +623,9 @@ static void transcode_audio_ffmpeg_close ( sout_stream_t *p_stream, sout_stream_
     free( id->ff_dec_c );
     free( id->ff_enc_c );
 
+    free( id->p_buffer_in );
     free( id->p_buffer );
+    free( id->p_buffer_out );
 }
 
 static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream, sout_stream_id_t *id,
@@ -649,8 +689,8 @@ static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream, sout_stream_
     }
     else
     {
-        int16_t *sout = (int16_t*)&id->p_buffer[id->i_buffer_pos];
-        int     i_used;
+        int16_t *sout  = (int16_t*)&id->p_buffer[id->i_buffer_pos];
+        int     i_used = 0;
 
         if( id->f_src.i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
         {
@@ -677,9 +717,9 @@ static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream, sout_stream_
         else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) )
         {
             int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos ) / 2, id->i_buffer_in_pos / 2);
-            i_used = i_samples * 2;
 #ifdef WORDS_BIGENDIAN
             uint8_t *sin = (uint8_t*)id->p_buffer_in;
+            i_used = i_samples * 2;
             while( i_samples > 0 )
             {
                 uint8_t tmp[2];
@@ -693,17 +733,19 @@ static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream, sout_stream_
 #else
             memcpy( sout, id->p_buffer_in, i_samples * 2 );
             sout += i_samples;
+            i_used = i_samples * 2;
 #endif
         }
         else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'b' ) )
         {
             int     i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos ) / 2, id->i_buffer_in_pos / 2);
-            i_used = i_samples * 2;
 #ifdef WORDS_BIGENDIAN
             memcpy( sout, id->p_buffer_in, i_samples * 2 );
             sout += i_samples;
+            i_used = i_samples * 2;
 #else
             uint8_t *sin = (uint8_t*)id->p_buffer_in;
+            i_used = i_samples * 2;
             while( i_samples > 0 )
             {
                 uint8_t tmp[2];
@@ -776,6 +818,8 @@ static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream, sout_stream_
  */
 static int transcode_video_ffmpeg_new   ( sout_stream_t *p_stream, sout_stream_id_t *id )
 {
+    sout_stream_sys_t   *p_sys = p_stream->p_sys;
+
     int i_ff_codec;
 
     if( id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '0' ) ||
@@ -863,9 +907,18 @@ static int transcode_video_ffmpeg_new   ( sout_stream_t *p_stream, sout_stream_i
 #else
     id->ff_enc_c->frame_rate     = 25 * FRAME_RATE_BASE;
 #endif
-    id->ff_enc_c->gop_size       = 25;
-    id->ff_enc_c->qmin           = 2;
-    id->ff_enc_c->qmax           = 31;
+    id->ff_enc_c->gop_size       = p_sys->i_key_int >= 0 ? p_sys->i_key_int : 50;
+
+    if( p_sys->i_vtolerance >= 0 )
+    {
+        id->ff_enc_c->bit_rate_tolerance = p_sys->i_vtolerance;
+    }
+    id->ff_enc_c->qmin           = p_sys->i_qmin;
+    id->ff_enc_c->qmax           = p_sys->i_qmax;
+    if( p_sys->b_hq )
+    {
+        id->ff_enc_c->flags      |= CODEC_FLAG_HQ;
+    }
 
     if( i_ff_codec == CODEC_ID_RAWVIDEO )
     {
@@ -938,6 +991,7 @@ static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream, sout_stream_
 static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, sout_stream_id_t *id,
                                            sout_buffer_t *in, sout_buffer_t **out )
 {
+    sout_stream_sys_t   *p_sys = p_stream->p_sys;
     int     i_used;
     int     i_out;
     int     b_gotpicture;
@@ -989,10 +1043,15 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, sout_stream_
         {
             /* XXX hack because of copy packetizer and mpeg4video that can failed
                detecting size */
-            if( id->ff_enc_c->width <= 0 || id->ff_enc_c->height <= 0 )
+            if( id->ff_enc_c->width <= 0 )
+            {
+                id->ff_enc_c->width    =
+                    id->f_dst.i_width  = id->ff_dec_c->width - p_sys->i_crop_left - p_sys->i_crop_right;
+            }
+            if( id->ff_enc_c->height <= 0 )
             {
-                id->ff_enc_c->width  = id->f_dst.i_width  = id->ff_dec_c->width;
-                id->ff_enc_c->height = id->f_dst.i_height = id->ff_dec_c->height;
+                id->ff_enc_c->height   =
+                    id->f_dst.i_height = id->ff_dec_c->height - p_sys->i_crop_top - p_sys->i_crop_bottom;
             }
 
             if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
@@ -1063,8 +1122,10 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, sout_stream_
         }
 
         /* convert size and crop */
-        if( ( id->ff_dec_c->width  != id->ff_enc_c->width ) ||
-            ( id->ff_dec_c->height != id->ff_enc_c->height ) )
+        if( id->ff_dec_c->width  != id->ff_enc_c->width ||
+            id->ff_dec_c->height != id->ff_enc_c->height ||
+            p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||
+            p_sys->i_crop_left > 0 || p_sys->i_crop_right )
         {
             if( id->p_ff_pic_tmp2 == NULL )
             {