shithub: opus

Download patch

ref: aa6fec669ef750837d3e4e3bdb903879b392caba
parent: 7e983194a3ac7c775c7d370a5bf6d71bf68c2645
author: Timothy B. Terriberry <[email protected]>
date: Tue Feb 1 10:36:59 EST 2011

Limit mode creation to supported modes.

We did no real error checking to see if a mode is supported when it
 is created.
This patch implements checks for Jean-Marc's rules:
1) A mode must have frames at least 1ms in length (no more than
    1000 per second).
2) A mode must have shorts of at most 3.33 ms (at least 300 per
    second).
It also adds error checking to dump_modes so we report the error
 instead of crashing when we fail to create a mode.

--- a/libcelt/dump_modes.c
+++ b/libcelt/dump_modes.c
@@ -34,6 +34,7 @@
 #include "config.h"
 #endif
 
+#include <stdlib.h>
 #include <stdio.h>
 #include "modes.h"
 #include "celt.h"
@@ -308,6 +309,12 @@
       Fs      = atoi(argv[2*i+1]);
       frame   = atoi(argv[2*i+2]);
       m[i] = celt_mode_create(Fs, frame, NULL);
+      if (m[i]==NULL)
+      {
+         fprintf(stderr,"Error creating mode with Fs=%s, frame_size=%s\n",
+               argv[2*i+1],argv[2*i+2]);
+         return EXIT_FAILURE;
+      }
    }
    file = fopen(BASENAME ".c", "w");
    dump_modes(file, m, nb);
--- a/libcelt/modes.c
+++ b/libcelt/modes.c
@@ -331,7 +331,35 @@
          *error = CELT_BAD_ARG;
       return NULL;
    }
-   
+   /* Frames of less than 1ms are not supported. */
+   if ((celt_int32)frame_size*1000 < Fs)
+   {
+      if (error)
+         *error = CELT_INVALID_MODE;
+      return NULL;
+   }
+
+   if ((celt_int32)frame_size*75 >= Fs && (frame_size%16)==0)
+   {
+     LM = 3;
+   } else if ((celt_int32)frame_size*150 >= Fs && (frame_size%8)==0)
+   {
+     LM = 2;
+   } else if ((celt_int32)frame_size*300 >= Fs && (frame_size%4)==0)
+   {
+     LM = 1;
+   } else if ((celt_int32)frame_size*300 <= Fs)
+   {
+     LM = 0;
+   }
+   /* Shorts longer than 3.3ms are not supported. */
+   else
+   {
+      if (error)
+         *error = CELT_INVALID_MODE;
+      return NULL;
+   }
+
    mode = celt_alloc(sizeof(CELTMode));
    if (mode==NULL)
       goto failure;
@@ -364,20 +392,6 @@
       mode->preemph[1] =  QCONST16(0.0f, 15);
       mode->preemph[2] =  QCONST16(1.f, SIG_SHIFT);
       mode->preemph[3] =  QCONST16(1.f, 13);
-   }
-
-   if ((celt_int32)frame_size*75 >= Fs && (frame_size%16)==0)
-   {
-     LM = 3;
-   } else if ((celt_int32)frame_size*150 >= Fs && (frame_size%8)==0)
-   {
-     LM = 2;
-   } else if ((celt_int32)frame_size*300 >= Fs && (frame_size%4)==0)
-   {
-     LM = 1;
-   } else
-   {
-     LM = 0;
    }
 
    mode->maxLM = LM;