diff options
author | Jean-Marc Valin <jmvalin@amazon.com> | 2023-05-19 09:31:11 +0300 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@amazon.com> | 2023-06-16 20:01:39 +0300 |
commit | e0c6eae8cc789b1d80babe5219d505fbf9d91a88 (patch) | |
tree | 50cbfe185c0524dbbfb77b385b88928b266980c7 /src | |
parent | a561f120c97f47d12baa56c33d351cbe8b579ddc (diff) |
Update the API to add an OpusDREDDecoder
Diffstat (limited to 'src')
-rw-r--r-- | src/opus_decoder.c | 81 | ||||
-rw-r--r-- | src/opus_demo.c | 5 |
2 files changed, 79 insertions, 7 deletions
diff --git a/src/opus_decoder.c b/src/opus_decoder.c index d0ef18f2..bf2f38ed 100644 --- a/src/opus_decoder.c +++ b/src/opus_decoder.c @@ -1089,6 +1089,69 @@ int opus_decoder_get_nb_samples(const OpusDecoder *dec, return opus_packet_get_nb_samples(packet, len, dec->Fs); } +struct OpusDREDDecoder { + int arch; + opus_uint32 magic; +}; + +#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS) +static void validate_dred_decoder(OpusDREDDecoder *st) +{ + celt_assert(st->magic == 0xD8EDDEC0); +#ifdef OPUS_ARCHMASK + celt_assert(st->arch >= 0); + celt_assert(st->arch <= OPUS_ARCHMASK); +#endif +} +#define VALIDATE_DRED_DECODER(st) validate_dred_decoder(st) +#else +#define VALIDATE_DRED_DECODER(st) +#endif + + +int opus_dred_decoder_get_size(void) +{ + return sizeof(OpusDREDDecoder); +} + +int opus_dred_decoder_init(OpusDREDDecoder *dec) +{ + dec->arch = opus_select_arch(); + /* To make sure nobody forgets to init, use a magic number. */ + dec->magic = 0xD8EDDEC0; + return OPUS_OK; +} + +OpusDREDDecoder *opus_dred_decoder_create(int *error) +{ + int ret; + OpusDREDDecoder *dec; + dec = (OpusDREDDecoder *)opus_alloc(opus_dred_get_size()); + if (dec == NULL) + { + if (error) + *error = OPUS_ALLOC_FAIL; + return NULL; + } + ret = opus_dred_decoder_init(dec); + if (error) + *error = ret; + if (ret != OPUS_OK) + { + opus_free(dec); + dec = NULL; + } + return dec; +} + +void opus_dred_decoder_destroy(OpusDREDDecoder *dec) +{ + dec->magic = 0xDE57801D; + free(dec); +} + + + #ifdef ENABLE_NEURAL_FEC static int dred_find_payload(const unsigned char *data, opus_int32 len, const unsigned char **payload) { @@ -1144,11 +1207,12 @@ static int dred_find_payload(const unsigned char *data, opus_int32 len, const un } #endif -int opus_dred_parse(OpusDRED *dred, const unsigned char *data, opus_int32 len, opus_int32 max_dred_samples, opus_int32 sampling_rate, int defer_processing) +int opus_dred_parse(OpusDREDDecoder *dred_dec, OpusDRED *dred, const unsigned char *data, opus_int32 len, opus_int32 max_dred_samples, opus_int32 sampling_rate, int defer_processing) { #ifdef ENABLE_NEURAL_FEC const unsigned char *payload; opus_int32 payload_len; + VALIDATE_DRED_DECODER(dred_dec); payload_len = dred_find_payload(data, len, &payload); if (payload_len < 0) return payload_len; @@ -1160,7 +1224,7 @@ int opus_dred_parse(OpusDRED *dred, const unsigned char *data, opus_int32 len, o min_feature_frames = IMIN(2 + offset, 2*DRED_NUM_REDUNDANCY_FRAMES); dred_ec_decode(dred, payload, payload_len, min_feature_frames); if (!defer_processing) - opus_dred_process(dred); + opus_dred_process(dred_dec, dred, dred); return dred->nb_latents*sampling_rate/25 - sampling_rate/50; } return 0; @@ -1175,13 +1239,18 @@ int opus_dred_parse(OpusDRED *dred, const unsigned char *data, opus_int32 len, o #endif } -int opus_dred_process(OpusDRED *dred) +int opus_dred_process(OpusDREDDecoder *dred_dec, const OpusDRED *src, OpusDRED *dst) { #ifdef ENABLE_NEURAL_FEC - if (dred->process_stage == 2) + if (dred_dec == NULL) + return OPUS_BAD_ARG; + VALIDATE_DRED_DECODER(dred_dec); + if (src != dst) + OPUS_COPY(dst, src, 1); + if (dst->process_stage == 2) return OPUS_OK; - DRED_rdovae_decode_all(dred->fec_features, dred->state, dred->latents, dred->nb_latents); - dred->process_stage = 2; + DRED_rdovae_decode_all(dst->fec_features, dst->state, dst->latents, dst->nb_latents); + dst->process_stage = 2; return OPUS_OK; #else (void)dred; diff --git a/src/opus_demo.c b/src/opus_demo.c index 2cad2986..7992050e 100644 --- a/src/opus_demo.c +++ b/src/opus_demo.c @@ -218,6 +218,7 @@ int main(int argc, char *argv[]) OpusEncoder *enc=NULL; OpusDecoder *dec=NULL; OpusDRED *dred=NULL; + OpusDREDDecoder *dred_dec=NULL; int args; int len; int frame_size, channels; @@ -630,6 +631,7 @@ int main(int argc, char *argv[]) opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration)); frame_size = 2*48000; } + dred_dec = opus_dred_decoder_create(&err); dred = opus_dred_create(&err); while (!stop) { @@ -803,7 +805,7 @@ int main(int argc, char *argv[]) opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples)); dred_input = lost_count*output_samples*100/sampling_rate; /* Only decode the amount we need to fill in the gap. */ - opus_dred_parse(dred, data, len, IMIN(100, IMAX(0, dred_input))*480, 48000, 0); + opus_dred_parse(dred_dec, dred, data, len, IMIN(100, IMAX(0, dred_input))*480, 48000, 0); } /* FIXME: Figure out how to trigger the decoder when the last packet of the file is lost. */ for (fr=0;fr<run_decoder;fr++) { @@ -917,6 +919,7 @@ failure: opus_encoder_destroy(enc); opus_decoder_destroy(dec); opus_dred_destroy(dred); + opus_dred_decoder_destroy(dred_dec); free(data); if (fin) fclose(fin); |