shithub: opus

Download patch

ref: 44ffd5a8daf0bf0e9ee48b181d64f3ed7a008df5
parent: 14f5e7cd09ca4728d394ddc78bdc03abb55ba06e
author: Jean-Marc Valin <[email protected]>
date: Thu Feb 21 19:39:25 EST 2008

Making sure freed or corrupted modes can't be used (produce a run-time warning).

--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -89,6 +89,10 @@
 {
    int i, N, B, C, N4;
    CELTEncoder *st;
+
+   if (check_mode(mode) != CELT_OK)
+      return NULL;
+
    N = mode->mdctSize;
    B = mode->nbMdctBlocks;
    C = mode->nbChannels;
@@ -135,6 +139,9 @@
       celt_warning("NULL passed to celt_encoder_destroy");
       return;
    }
+   if (check_mode(st->mode) != CELT_OK)
+      return;
+
    ec_byte_writeclear(&st->buf);
 
    mdct_clear(&st->mdct_lookup);
@@ -224,6 +231,10 @@
    VARDECL(float *mask);
    VARDECL(float *bandE);
    VARDECL(float *gains);
+
+   if (check_mode(st->mode) != CELT_OK)
+      return CELT_INVALID_MODE;
+
    N = st->block_size;
    B = st->nb_blocks;
    C = st->mode->nbChannels;
@@ -450,6 +461,10 @@
 {
    int i, N, B, C, N4;
    CELTDecoder *st;
+
+   if (check_mode(mode) != CELT_OK)
+      return NULL;
+
    N = mode->mdctSize;
    B = mode->nbMdctBlocks;
    C = mode->nbChannels;
@@ -493,6 +508,8 @@
       celt_warning("NULL passed to celt_encoder_destroy");
       return;
    }
+   if (check_mode(st->mode) != CELT_OK)
+      return;
 
    mdct_clear(&st->mdct_lookup);
 
@@ -556,6 +573,10 @@
    VARDECL(float *P);
    VARDECL(float *bandE);
    VARDECL(float *gains);
+
+   if (check_mode(st->mode) != CELT_OK)
+      return CELT_INVALID_MODE;
+
    N = st->block_size;
    B = st->nb_blocks;
    C = st->mode->nbChannels;
@@ -565,6 +586,8 @@
    ALLOC(bandE, st->mode->nbEBands*C, float);
    ALLOC(gains, st->mode->nbPBands, float);
    
+   if (check_mode(st->mode) != CELT_OK)
+      return CELT_INVALID_MODE;
    if (data == NULL)
    {
       celt_decode_lost(st, pcm);
--- a/libcelt/modes.c
+++ b/libcelt/modes.c
@@ -38,6 +38,10 @@
 #include "rate.h"
 #include "os_support.h"
 
+#define MODEVALID 0xa110ca7e
+#define MODEFREED 0xb10cf8ee
+
+
 int celt_mode_info(const CELTMode *mode, int request, celt_int32_t *value)
 {
    switch (request)
@@ -255,6 +259,8 @@
    compute_allocation_table(mode, res);
    compute_alloc_cache(mode);
    /*printf ("%d bands\n", mode->nbEBands);*/
+   mode->marker_start = MODEVALID;
+   mode->marker_end = MODEVALID;
    return mode;
 }
 
@@ -262,6 +268,8 @@
 {
    int i;
    const int *prevPtr = NULL;
+   if (check_mode(mode) != CELT_OK)
+      return;
    celt_free((int*)mode->eBands);
    celt_free((int*)mode->pBands);
    celt_free((int*)mode->allocVectors);
@@ -275,7 +283,19 @@
       }
    }
    celt_free((int**)mode->bits);
-
+   mode->marker_start = MODEFREED;
+   mode->marker_end = MODEFREED;
    celt_free((CELTMode *)mode);
 
+}
+
+int check_mode(const CELTMode *mode)
+{
+   if (mode->marker_start == MODEVALID && mode->marker_end == MODEVALID)
+      return CELT_OK;
+   if (mode->marker_start == MODEFREED || mode->marker_end == MODEFREED)
+      celt_warning("Using a mode that has already been freed");
+   else
+      celt_warning("This is not a valid CELT mode");
+   return CELT_INVALID_MODE;
 }
--- a/libcelt/modes.h
+++ b/libcelt/modes.h
@@ -39,7 +39,8 @@
  @brief Mode definition 
  */
 struct CELTMode {
-   int          Fs;
+   celt_int32_t marker_start;
+   celt_int32_t Fs;
    int          overlap;
    int          mdctSize;
    int          nbMdctBlocks;
@@ -58,7 +59,9 @@
    const int   *allocVectors;   /**< Number of bits in each band for several rates */
    
    const int * const *bits; /**< Cache for pulses->bits mapping in each band */
-
+   celt_int32_t marker_end;
 };
+
+int check_mode(const CELTMode *mode);
 
 #endif
--- a/tools/celtenc.c
+++ b/tools/celtenc.c
@@ -221,6 +221,7 @@
    printf (" -V                 Verbose mode (show bit-rate)\n"); 
    printf ("Raw input options:\n");
    printf (" --rate n           Sampling rate for raw input\n"); 
+   printf (" --mono             Consider raw input as mono\n"); 
    printf (" --stereo           Consider raw input as stereo\n"); 
    printf (" --le               Raw input is little-endian\n"); 
    printf (" --be               Raw input is big-endian\n"); 
@@ -255,6 +256,7 @@
       {"be", no_argument, NULL, 0},
       {"8bit", no_argument, NULL, 0},
       {"16bit", no_argument, NULL, 0},
+      {"mono", no_argument, NULL, 0},
       {"stereo", no_argument, NULL, 0},
       {"rate", required_argument, NULL, 0},
       {"version", no_argument, NULL, 0},
@@ -339,7 +341,9 @@
          } else if (strcmp(long_options[option_index].name,"stereo")==0)
          {
             chan=2;
-            mode = celt_stereo;
+         } else if (strcmp(long_options[option_index].name,"mono")==0)
+         {
+            chan=1;
          } else if (strcmp(long_options[option_index].name,"rate")==0)
          {
             rate=atoi (optarg);