ref: b1e017f58d2bb319eb7bc3305048185a9c8fe9d9
parent: 9d785afb677256b26c5c51ad08e5b321f9ec7640
author: Jean-Marc Valin <[email protected]>
date: Sun Jul 18 17:20:35 EDT 2010
Error checking on the decoder side
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -1104,7 +1104,7 @@
ec_enc_done(enc);
RESTORE_STACK;
- if (enc->error)
+ if (ec_enc_get_error(enc))
return CELT_CORRUPTED_DATA;
else
return nbCompressedBytes;
@@ -1734,7 +1734,7 @@
{
celt_decode_lost(st, pcm, N, LM);
RESTORE_STACK;
- return 0;
+ return CELT_OK;
}
if (len<0) {
RESTORE_STACK;
@@ -1785,6 +1785,7 @@
if (maxpitch<0)
{
celt_notify("detected pitch when not allowed, bit corruption suspected");
+ dec->error |= 1;
pitch_index = 0;
has_pitch = 0;
} else {
@@ -1856,7 +1857,10 @@
deemphasis(st->out_mem, pcm, N, C, st->mode->preemph, st->preemph_memD);
st->loss_count = 0;
RESTORE_STACK;
- return 0;
+ if (ec_dec_get_error(dec))
+ return CELT_CORRUPTED_DATA;
+ else
+ return CELT_OK;
}
#ifdef FIXED_POINT
@@ -1888,8 +1892,9 @@
ALLOC(out, C*N, celt_int16);
ret=celt_decode_with_ec(st, data, len, out, frame_size, dec);
- for (j=0;j<C*N;j++)
- pcm[j]=out[j]*(1/32768.);
+ if (ret==0)
+ for (j=0;j<C*N;j++)
+ pcm[j]=out[j]*(1/32768.);
RESTORE_STACK;
return ret;
@@ -1924,8 +1929,9 @@
ret=celt_decode_with_ec_float(st, data, len, out, frame_size, dec);
- for (j=0;j<C*N;j++)
- pcm[j] = FLOAT2INT16 (out[j]);
+ if (ret==0)
+ for (j=0;j<C*N;j++)
+ pcm[j] = FLOAT2INT16 (out[j]);
RESTORE_STACK;
return ret;
--- a/libcelt/entdec.c
+++ b/libcelt/entdec.c
@@ -99,8 +99,9 @@
t = t<<ftb|ec_dec_bits(_this,ftb);
if (t>_ft)
{
- celt_notify("uint decode error");
- t = _ft;
+ celt_notify("uint decode error");
+ _this->error |= 1;
+ t = _ft;
}
return t;
} else {
@@ -110,4 +111,9 @@
t=t<<ftb|s;
return t;
}
+}
+
+int ec_dec_get_error(ec_dec *_this)
+{
+ return _this->error || (ec_dec_tell(_this,0) > 8*_this->buf->storage);
}
--- a/libcelt/entdec.h
+++ b/libcelt/entdec.h
@@ -56,6 +56,8 @@
/*Number of valid bits in end_byte*/
int end_bits_left;
int nb_end_bits;
+ /*Nonzero if an error occurred*/
+ int error;
};
@@ -122,5 +124,8 @@
This will always be slightly larger than the exact value (e.g., all
rounding error is in the positive direction).*/
long ec_dec_tell(ec_dec *_this,int _b);
+
+/*Returns a nonzero value if any error has been detected during decoding*/
+int ec_dec_get_error(ec_dec *_this);
#endif
--- a/libcelt/entenc.c
+++ b/libcelt/entenc.c
@@ -102,3 +102,8 @@
ec_encode(_this,_fl,_fl+1,_ft+1);
}
}
+
+int ec_enc_get_error(ec_enc *_this)
+{
+ return _this->error;
+}
--- a/libcelt/entenc.h
+++ b/libcelt/entenc.h
@@ -57,7 +57,7 @@
/*Number of valid bits in end_byte*/
int end_bits_left;
int nb_end_bits;
- /*Nonzero is an error occurred*/
+ /*Nonzero if an error occurred*/
int error;
};
@@ -110,5 +110,8 @@
All reamining output bytes are flushed to the output buffer.
ec_enc_init() must be called before the encoder can be used again.*/
void ec_enc_done(ec_enc *_this);
+
+/*Returns a nonzero value if any error has been detected during encoding*/
+int ec_enc_get_error(ec_enc *_this);
#endif
--- a/libcelt/rangedec.c
+++ b/libcelt/rangedec.c
@@ -144,6 +144,7 @@
/*_this->end_byte=ec_byte_look_at_end(_this->buf);*/
_this->end_bits_left=0;
_this->nb_end_bits=0;
+ _this->error=0;
}
--- a/libcelt/testcelt.c
+++ b/libcelt/testcelt.c
@@ -136,10 +136,8 @@
break;
len = celt_encode_resynthesis(enc, in, in, frame_size, data, bytes_per_packet);
if (len <= 0)
- {
- fprintf (stderr, "celt_encode() returned an error: %s\n", celt_strerror(len));
- return 1;
- }
+ fprintf (stderr, "celt_encode() failed: %s\n", celt_strerror(len));
+
/* This is for simulating bit errors */
#if 0
int errors = 0;
@@ -162,13 +160,16 @@
else if (errors%2 == 1)
data[rand()%8] ^= 1<<rand()%8;
#endif
+
#if 1 /* Set to zero to use the encoder's output instead */
/* This is to simulate packet loss */
if (argc==9 && rand()%1000<atoi(argv[argc-3]))
/*if (errors && (errors%2==0))*/
- celt_decode(dec, NULL, len, out, frame_size);
+ err = celt_decode(dec, NULL, len, out, frame_size);
else
- celt_decode(dec, data, len, out, frame_size);
+ err = celt_decode(dec, data, len, out, frame_size);
+ if (err != 0)
+ fprintf(stderr, "celt_decode() failed: %s\n", celt_strerror(err));
#else
for (i=0;i<frame_size*channels;i++)
out[i] = in[i];