Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.xiph.org/xiph/opus.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@amazon.com>2023-05-19 09:31:11 +0300
committerJean-Marc Valin <jmvalin@amazon.com>2023-06-16 20:01:39 +0300
commite0c6eae8cc789b1d80babe5219d505fbf9d91a88 (patch)
tree50cbfe185c0524dbbfb77b385b88928b266980c7 /src
parenta561f120c97f47d12baa56c33d351cbe8b579ddc (diff)
Update the API to add an OpusDREDDecoder
Diffstat (limited to 'src')
-rw-r--r--src/opus_decoder.c81
-rw-r--r--src/opus_demo.c5
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);