summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@amazon.com>2022-11-30 15:56:33 -0500
committerJean-Marc Valin <jmvalin@amazon.com>2022-11-30 15:56:33 -0500
commitf61282cab9f2580db64e5a48ebb224c5acb4fba0 (patch)
treef7e410177de5fdaaf89c539176e09b21ac61ff9b
parent43779321d5cf41b3133f62c8e1ad30b066af124f (diff)
downloadopus-exp_neural_fec2c.tar.gz
Code for extracting DRED from packetexp_neural_fec2c
-rw-r--r--include/opus.h3
-rw-r--r--src/extensions.c2
-rw-r--r--src/opus.c10
-rw-r--r--src/opus_decoder.c53
-rw-r--r--src/opus_encoder.c6
-rw-r--r--src/opus_multistream_decoder.c2
-rw-r--r--src/opus_private.h6
-rw-r--r--src/repacketizer.c6
8 files changed, 76 insertions, 12 deletions
diff --git a/include/opus.h b/include/opus.h
index 0c69c627..d96c9d6b 100644
--- a/include/opus.h
+++ b/include/opus.h
@@ -511,6 +511,9 @@ OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NON
*/
OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st);
+OPUS_EXPORT int opus_decoder_dred_input(OpusDecoder *st, const unsigned char *data,
+ opus_int32 len, int offset) OPUS_ARG_NONNULL(1);
+
/** Parse an opus packet into one or more frames.
* Opus_decode will perform this operation internally so most applications do
* not need to use this function.
diff --git a/src/extensions.c b/src/extensions.c
index b7bafb99..e899ad2b 100644
--- a/src/extensions.c
+++ b/src/extensions.c
@@ -38,7 +38,7 @@
/* Given an extension payload, advance data to the next extension and return the
length of the remaining extensions. */
-static opus_int32 skip_extension(const unsigned char **data, opus_int32 len, opus_int32 *header_size)
+opus_int32 skip_extension(const unsigned char **data, opus_int32 len, opus_int32 *header_size)
{
int id, L;
if (len==0)
diff --git a/src/opus.c b/src/opus.c
index 538b5ea7..816a4dd5 100644
--- a/src/opus.c
+++ b/src/opus.c
@@ -194,7 +194,8 @@ int opus_packet_get_samples_per_frame(const unsigned char *data,
int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
int self_delimited, unsigned char *out_toc,
const unsigned char *frames[48], opus_int16 size[48],
- int *payload_offset, opus_int32 *packet_offset)
+ int *payload_offset, opus_int32 *packet_offset,
+ const unsigned char **padding, opus_int32 *padding_len)
{
int i, bytes;
int count;
@@ -337,6 +338,11 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
data += size[i];
}
+ if (padding != NULL)
+ {
+ *padding = data;
+ *padding_len = pad;
+ }
if (packet_offset)
*packet_offset = pad+(opus_int32)(data-data0);
@@ -351,6 +357,6 @@ int opus_packet_parse(const unsigned char *data, opus_int32 len,
opus_int16 size[48], int *payload_offset)
{
return opus_packet_parse_impl(data, len, 0, out_toc,
- frames, size, payload_offset, NULL);
+ frames, size, payload_offset, NULL, NULL, NULL);
}
diff --git a/src/opus_decoder.c b/src/opus_decoder.c
index 6520e748..8cd58a91 100644
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -672,7 +672,7 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data,
packet_stream_channels = opus_packet_get_nb_channels(data);
count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL,
- size, &offset, packet_offset);
+ size, &offset, packet_offset, NULL, NULL);
if (count<0)
return count;
@@ -1039,3 +1039,54 @@ int opus_decoder_get_nb_samples(const OpusDecoder *dec,
{
return opus_packet_get_nb_samples(packet, len, dec->Fs);
}
+
+int opus_decoder_dred_input(OpusDecoder *st, const unsigned char *data,
+ opus_int32 len, int offset)
+{
+ const unsigned char *data0;
+ int len0;
+ const unsigned char *payload = NULL;
+ opus_int32 payload_len;
+ int frame = 0;
+ int ret;
+ const unsigned char *frames[48];
+ opus_int16 size[48];
+
+ /* Get the padding section of the packet. */
+ ret = opus_packet_parse_impl(data, len, 0, NULL, frames, size, NULL, NULL, &data0, &len0);
+ data = data0;
+ len = len0;
+ /* Scan extensions in order until we find the earliest frame with DRED data. */
+ while (len > 0)
+ {
+ opus_int32 header_size;
+ int id, L;
+ len0 = len;
+ data0 = data;
+ id = *data0 >> 1;
+ L = *data0 & 0x1;
+ len = skip_extension(&data, len, &header_size);
+ if (len < 0)
+ break;
+ if (id == 1)
+ {
+ if (L==0)
+ {
+ frame++;
+ } else {
+ frame += data[1];
+ }
+ } else if (id == 127)
+ {
+ payload = data0+header_size;
+ payload_len = (data-data0)-header_size;
+ break;
+ }
+ }
+ if (payload != NULL)
+ {
+ /* Found something -- do the decoding. */
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/opus_encoder.c b/src/opus_encoder.c
index a8afbf89..a9fe94dd 100644
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -2179,9 +2179,9 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
}
/* Count ToC and redundancy */
ret += 1+redundancy_bytes;
- if (1) {
- opus_extension_data extension = {33, 0, (const unsigned char *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 50};
- ret = opus_packet_pad_impl(data, ret, max_data_bytes, !st->use_vbr, &extension, 1);
+ if (0) {
+ opus_extension_data extension = {127, 0, (const unsigned char *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 50};
+ ret = opus_packet_pad_impl(data, ret, max_data_bytes, !st->use_vbr, extension, 1);
if (ret < 0)
{
RESTORE_STACK;
diff --git a/src/opus_multistream_decoder.c b/src/opus_multistream_decoder.c
index a2837c35..9648c4a7 100644
--- a/src/opus_multistream_decoder.c
+++ b/src/opus_multistream_decoder.c
@@ -162,7 +162,7 @@ static int opus_multistream_packet_validate(const unsigned char *data,
if (len<=0)
return OPUS_INVALID_PACKET;
count = opus_packet_parse_impl(data, len, s!=nb_streams-1, &toc, NULL,
- size, NULL, &packet_offset);
+ size, NULL, &packet_offset, NULL, NULL);
if (count<0)
return count;
tmp_samples = opus_packet_get_nb_samples(data, packet_offset, Fs);
diff --git a/src/opus_private.h b/src/opus_private.h
index 113071fa..4fcd9e34 100644
--- a/src/opus_private.h
+++ b/src/opus_private.h
@@ -169,10 +169,14 @@ static OPUS_INLINE int align(int i)
return ((i + alignment - 1) / alignment) * alignment;
}
+/* More than that is ridiculous for now (3 * max frames per packet)*/
+opus_int32 skip_extension(const unsigned char **data, opus_int32 len, opus_int32 *header_size);
+
int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
int self_delimited, unsigned char *out_toc,
const unsigned char *frames[48], opus_int16 size[48],
- int *payload_offset, opus_int32 *packet_offset);
+ int *payload_offset, opus_int32 *packet_offset,
+ const unsigned char **padding, opus_int32 *padding_len);
opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end,
unsigned char *data, opus_int32 maxlen, int self_delimited, int pad,
diff --git a/src/repacketizer.c b/src/repacketizer.c
index 3ae8ee36..df283ac8 100644
--- a/src/repacketizer.c
+++ b/src/repacketizer.c
@@ -82,7 +82,7 @@ static int opus_repacketizer_cat_impl(OpusRepacketizer *rp, const unsigned char
return OPUS_INVALID_PACKET;
}
- ret=opus_packet_parse_impl(data, len, self_delimited, &tmp_toc, &rp->frames[rp->nb_frames], &rp->len[rp->nb_frames], NULL, NULL);
+ ret=opus_packet_parse_impl(data, len, self_delimited, &tmp_toc, &rp->frames[rp->nb_frames], &rp->len[rp->nb_frames], NULL, NULL, NULL, NULL);
if(ret<1)return ret;
rp->nb_frames += curr_nb_frames;
@@ -316,7 +316,7 @@ int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32
if (len<=0)
return OPUS_INVALID_PACKET;
count = opus_packet_parse_impl(data, len, 1, &toc, NULL,
- size, NULL, &packet_offset);
+ size, NULL, &packet_offset, NULL, NULL);
if (count<0)
return count;
data += packet_offset;
@@ -348,7 +348,7 @@ opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, in
return OPUS_INVALID_PACKET;
opus_repacketizer_init(&rp);
ret = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL,
- size, NULL, &packet_offset);
+ size, NULL, &packet_offset, NULL, NULL);
if (ret<0)
return ret;
ret = opus_repacketizer_cat_impl(&rp, data, packet_offset, self_delimited);