]> git.sesse.net Git - vlc/commitdiff
* modules/codec/twolame.c, modules/codec/ffmpeg/encoder.c: Added sanity
authorChristophe Massiot <massiot@videolan.org>
Mon, 1 Aug 2005 14:50:42 +0000 (14:50 +0000)
committerChristophe Massiot <massiot@videolan.org>
Mon, 1 Aug 2005 14:50:42 +0000 (14:50 +0000)
   checks for frequencies and bitrates in MPEG audio.

modules/codec/ffmpeg/encoder.c
modules/codec/twolame.c

index 60570a31869351c5600fa503fec19c3d225bee0b..326d8118c6c9115e879a940f207da84e90d3b352 100644 (file)
@@ -157,6 +157,15 @@ static const char *ppsz_enc_options[] = {
     "chroma-elim-threshold", NULL
 };
 
+static const uint16_t mpa_bitrate_tab[2][15] =
+{
+    {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384},
+    {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
+};
+
+static const uint16_t mpa_freq_tab[6] =
+{ 44100, 48000, 32000, 22050, 24000, 16000 };
+
 /*****************************************************************************
  * OpenEncoder: probe the encoder
  *****************************************************************************/
@@ -516,17 +525,61 @@ int E_(OpenEncoder)( vlc_object_t *p_this )
 
     if( avcodec_open( p_context, p_codec ) )
     {
-        if( p_enc->fmt_in.i_cat == AUDIO_ES && p_context->channels > 2 )
+        if( p_enc->fmt_in.i_cat == AUDIO_ES &&
+             (p_context->channels > 2 || i_codec_id == CODEC_ID_MP2
+               || i_codec_id == CODEC_ID_MP3) )
         {
-            p_context->channels = 2;
-            p_enc->fmt_in.audio.i_channels = 2; // FIXME
+            if( p_context->channels > 2 )
+            {
+                p_context->channels = 2;
+                p_enc->fmt_in.audio.i_channels = 2; // FIXME
+                msg_Warn( p_enc, "stereo mode selected (codec limitation)" );
+            }
+
+            if( i_codec_id == CODEC_ID_MP2 || i_codec_id == CODEC_ID_MP3 )
+            {
+                int i_frequency, i;
+
+                for ( i_frequency = 0; i_frequency < 6; i_frequency++ )
+                {
+                    if ( p_enc->fmt_out.audio.i_rate
+                            == mpa_freq_tab[i_frequency] )
+                        break;
+                }
+                if ( i_frequency == 6 )
+                {
+                    msg_Err( p_enc, "MPEG audio doesn't support frequency=%d",
+                             p_enc->fmt_out.audio.i_rate );
+                    free( p_sys );
+                    return VLC_EGENERIC;
+                }
+
+                for ( i = 1; i < 14; i++ )
+                {
+                    if ( p_enc->fmt_out.i_bitrate / 1000
+                          <= mpa_bitrate_tab[i_frequency / 3][i] )
+                        break;
+                }
+                if ( p_enc->fmt_out.i_bitrate / 1000
+                      != mpa_bitrate_tab[i_frequency / 3][i] )
+                {
+                    msg_Warn( p_enc,
+                              "MPEG audio doesn't support bitrate=%d, using %d",
+                              p_enc->fmt_out.i_bitrate,
+                              mpa_bitrate_tab[i_frequency / 3][i] * 1000 );
+                    p_enc->fmt_out.i_bitrate =
+                        mpa_bitrate_tab[i_frequency / 3][i] * 1000;
+                    p_context->bit_rate = p_enc->fmt_out.i_bitrate;
+                }
+            }
+
+            p_context->codec = NULL;
             if( avcodec_open( p_context, p_codec ) )
             {
                 msg_Err( p_enc, "cannot open encoder" );
                 free( p_sys );
                 return VLC_EGENERIC;
             }
-            msg_Warn( p_enc, "stereo mode selected (codec limitation)" );
         }
         else
         {
index 3d99d15750dafe741a678b64199852f3076a68d7..42d90f0dc5f496547b18ad452452403ddc8cd901 100644 (file)
@@ -106,11 +106,21 @@ struct encoder_sys_t
 /*****************************************************************************
  * OpenEncoder: probe the encoder and return score
  *****************************************************************************/
+static const uint16_t mpa_bitrate_tab[2][15] =
+{
+    {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384},
+    {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
+};
+
+static const uint16_t mpa_freq_tab[6] =
+{ 44100, 48000, 32000, 22050, 24000, 16000 };
+
 static int OpenEncoder( vlc_object_t *p_this )
 {
     encoder_t *p_enc = (encoder_t *)p_this;
     encoder_sys_t *p_sys;
     vlc_value_t val;
+    int i_frequency;
 
     if( p_enc->fmt_out.i_codec != VLC_FOURCC('m','p','g','a') &&
         p_enc->fmt_out.i_codec != VLC_FOURCC('m','p','2','a') &&
@@ -126,6 +136,18 @@ static int OpenEncoder( vlc_object_t *p_this )
         return VLC_EGENERIC;
     }
 
+    for ( i_frequency = 0; i_frequency < 6; i_frequency++ )
+    {
+        if ( p_enc->fmt_out.audio.i_rate == mpa_freq_tab[i_frequency] )
+            break;
+    }
+    if ( i_frequency == 6 )
+    {
+        msg_Err( p_enc, "MPEG audio doesn't support frequency=%d",
+                 p_enc->fmt_out.audio.i_rate );
+        return VLC_EGENERIC;
+    }
+
     /* Allocate the memory needed to store the decoder's structure */
     if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
     {
@@ -159,7 +181,25 @@ static int OpenEncoder( vlc_object_t *p_this )
     }
     else
     {
-        twolame_set_bitrate( p_sys->p_twolame, p_enc->fmt_out.i_bitrate / 1000 );
+        int i;
+        for ( i = 1; i < 14; i++ )
+        {
+            if ( p_enc->fmt_out.i_bitrate / 1000
+                  <= mpa_bitrate_tab[i_frequency / 3][i] )
+                break;
+        }
+        if ( p_enc->fmt_out.i_bitrate / 1000
+              != mpa_bitrate_tab[i_frequency / 3][i] )
+        {
+            msg_Warn( p_enc, "MPEG audio doesn't support bitrate=%d, using %d",
+                      p_enc->fmt_out.i_bitrate,
+                      mpa_bitrate_tab[i_frequency / 3][i] * 1000 );
+            p_enc->fmt_out.i_bitrate = mpa_bitrate_tab[i_frequency / 3][i]
+                                        * 1000;
+        }
+
+        twolame_set_bitrate( p_sys->p_twolame,
+                             p_enc->fmt_out.i_bitrate / 1000 );
     }
 
     if ( p_enc->fmt_in.audio.i_channels == 1 )