]> git.sesse.net Git - vlc/blobdiff - modules/codec/twolame.c
avcodec: fix double free
[vlc] / modules / codec / twolame.c
index 041357b2919d5e0c1bb278b2b04a26cd2d6165b4..79c64b7ebe6da2ca18805dc4ef43f434596cbbb4 100644 (file)
@@ -177,8 +177,8 @@ static int OpenEncoder( vlc_object_t *p_this )
     if( var_GetBool( p_enc, ENC_CFG_PREFIX "vbr" ) )
     {
         float f_quality = var_GetFloat( p_enc, ENC_CFG_PREFIX "quality" );
-        if ( f_quality > 50.0 ) f_quality = 50.0;
-        if ( f_quality < 0.0 ) f_quality = 0.0;
+        if ( f_quality > 50.f ) f_quality = 50.f;
+        if ( f_quality < 0.f ) f_quality = 0.f;
         twolame_set_VBR( p_sys->p_twolame, 1 );
         twolame_set_VBR_q( p_sys->p_twolame, f_quality );
     }
@@ -251,12 +251,24 @@ static int OpenEncoder( vlc_object_t *p_this )
  ****************************************************************************/
 static void Bufferize( encoder_t *p_enc, int16_t *p_in, int i_nb_samples )
 {
-    int16_t *p_buffer = p_enc->p_sys->p_buffer
-                         + (p_enc->p_sys->i_nb_samples
-                             * p_enc->fmt_in.audio.i_channels);
+    encoder_sys_t *p_sys = p_enc->p_sys;
+    const unsigned i_offset = p_sys->i_nb_samples * p_enc->fmt_in.audio.i_channels;
+    const unsigned i_len = ARRAY_SIZE(p_sys->p_buffer);
 
-    memcpy( p_buffer, p_in, i_nb_samples * p_enc->fmt_in.audio.i_channels
-                             * sizeof(int16_t) );
+    if( i_offset >= i_len )
+    {
+        msg_Err( p_enc, "buffer full" );
+        return;
+    }
+
+    unsigned i_copy = i_nb_samples * p_enc->fmt_in.audio.i_channels;
+    if( i_copy + i_offset > i_len)
+    {
+        msg_Err( p_enc, "dropping samples" );
+        i_copy = i_len - i_offset;
+    }
+
+    memcpy( p_sys->p_buffer + i_offset, p_in, i_copy * sizeof(int16_t) );
 }
 
 static block_t *Encode( encoder_t *p_enc, block_t *p_aout_buf )
@@ -270,13 +282,14 @@ static block_t *Encode( encoder_t *p_enc, block_t *p_aout_buf )
 
         i_used = twolame_encode_flush( p_sys->p_twolame,
                                 p_sys->p_out_buffer, MAX_CODED_FRAME_SIZE );
-
-        if( i_used < 0 )
+        if( i_used <= 0 )
             return NULL;
 
         p_block = block_Alloc( i_used );
+        if( !p_block )
+            return NULL;
         memcpy( p_block->p_buffer, p_sys->p_out_buffer, i_used );
-        p_block->i_length = (mtime_t)1000000 *
+        p_block->i_length = CLOCK_FREQ *
                 (mtime_t)MPEG_FRAME_SIZE / (mtime_t)p_enc->fmt_out.audio.i_rate;
         p_block->i_dts = p_block->i_pts = p_sys->i_pts;
         p_sys->i_pts += p_block->i_length;
@@ -303,10 +316,23 @@ static block_t *Encode( encoder_t *p_enc, block_t *p_aout_buf )
         i_used = twolame_encode_buffer_interleaved( p_sys->p_twolame,
                                p_sys->p_buffer, MPEG_FRAME_SIZE,
                                p_sys->p_out_buffer, MAX_CODED_FRAME_SIZE );
+        /* On error, buffer samples and return what was already encoded */
+        if( i_used < 0 )
+        {
+            msg_Err( p_enc, "encoder error: %d", i_used );
+            break;
+        }
+
         p_sys->i_nb_samples = 0;
         p_block = block_Alloc( i_used );
+        if( !p_block )
+        {
+            if( p_chain )
+                block_ChainRelease( p_chain );
+            return NULL;
+        }
         memcpy( p_block->p_buffer, p_sys->p_out_buffer, i_used );
-        p_block->i_length = (mtime_t)1000000 *
+        p_block->i_length = CLOCK_FREQ *
                 (mtime_t)MPEG_FRAME_SIZE / (mtime_t)p_enc->fmt_out.audio.i_rate;
         p_block->i_dts = p_block->i_pts = p_sys->i_pts;
         p_sys->i_pts += p_block->i_length;