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);