libopus: updated to 1.1
Looks like a major update, with better performances for ARM.
diff --git a/jni/libopus/sources/src/opus_demo.c b/jni/libopus/sources/src/opus_demo.c
index 9a03eae..f8cdf03 100644
--- a/jni/libopus/sources/src/opus_demo.c
+++ b/jni/libopus/sources/src/opus_demo.c
@@ -38,6 +38,7 @@
#include "debug.h"
#include "opus_types.h"
#include "opus_private.h"
+#include "opus_multistream.h"
#define MAX_PACKET 1500
@@ -53,6 +54,7 @@
fprintf(stderr, "-d : only runs the decoder (reads the bit-stream as input)\n" );
fprintf(stderr, "-cbr : enable constant bitrate; default: variable bitrate\n" );
fprintf(stderr, "-cvbr : enable constrained variable bitrate; default: unconstrained\n" );
+ fprintf(stderr, "-variable-duration : enable frames of variable duration (experts only); default: disabled\n" );
fprintf(stderr, "-bandwidth <NB|MB|WB|SWB|FB> : audio bandwidth (from narrowband to fullband); default: sampling rate\n" );
fprintf(stderr, "-framesize <2.5|5|10|20|40|60> : frame size in ms; default: 20 \n" );
fprintf(stderr, "-max_payload <bytes> : maximum payload size in bytes, default: 1024\n" );
@@ -77,15 +79,6 @@
| ((opus_uint32)ch[2]<< 8) | (opus_uint32)ch[3];
}
-static void check_decoder_option(int encode_only, const char *opt)
-{
- if (encode_only)
- {
- fprintf(stderr, "option %s is only for decoding\n", opt);
- exit(EXIT_FAILURE);
- }
-}
-
static void check_encoder_option(int decode_only, const char *opt)
{
if (decode_only)
@@ -192,6 +185,35 @@
{MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 2},
};
+#if 0 /* This is a hack that replaces the normal encoder/decoder with the multistream version */
+#define OpusEncoder OpusMSEncoder
+#define OpusDecoder OpusMSDecoder
+#define opus_encode opus_multistream_encode
+#define opus_decode opus_multistream_decode
+#define opus_encoder_ctl opus_multistream_encoder_ctl
+#define opus_decoder_ctl opus_multistream_decoder_ctl
+#define opus_encoder_create ms_opus_encoder_create
+#define opus_decoder_create ms_opus_decoder_create
+#define opus_encoder_destroy opus_multistream_encoder_destroy
+#define opus_decoder_destroy opus_multistream_decoder_destroy
+
+static OpusEncoder *ms_opus_encoder_create(opus_int32 Fs, int channels, int application, int *error)
+{
+ int streams, coupled_streams;
+ unsigned char mapping[256];
+ return (OpusEncoder *)opus_multistream_surround_encoder_create(Fs, channels, 1, &streams, &coupled_streams, mapping, application, error);
+}
+static OpusDecoder *ms_opus_decoder_create(opus_int32 Fs, int channels, int *error)
+{
+ int streams;
+ int coupled_streams;
+ unsigned char mapping[256]={0,1};
+ streams = 1;
+ coupled_streams = channels==2;
+ return (OpusDecoder *)opus_multistream_decoder_create(Fs, channels, streams, coupled_streams, mapping, error);
+}
+#endif
+
int main(int argc, char *argv[])
{
int err;
@@ -221,6 +243,8 @@
short *in, *out;
int application=OPUS_APPLICATION_AUDIO;
double bits=0.0, bits_max=0.0, bits_act=0.0, bits2=0.0, nrg;
+ double tot_samples=0;
+ opus_uint64 tot_in, tot_out;
int bandwidth=-1;
const char *bandwidth_string;
int lost = 0, lost_prev = 1;
@@ -239,6 +263,10 @@
int curr_mode=0;
int curr_mode_count=0;
int mode_switch_time = 48000;
+ int nb_encoded=0;
+ int remaining=0;
+ int variable_duration=OPUS_FRAMESIZE_ARG;
+ int delayed_decision=0;
if (argc < 5 )
{
@@ -246,6 +274,7 @@
return EXIT_FAILURE;
}
+ tot_in=tot_out=0;
fprintf(stderr, "%s\n", opus_get_version_string());
args = 1;
@@ -279,13 +308,6 @@
}
sampling_rate = (opus_int32)atol(argv[args]);
args++;
- channels = atoi(argv[args]);
- args++;
- if (!decode_only)
- {
- bitrate_bps = (opus_int32)atol(argv[args]);
- args++;
- }
if (sampling_rate != 8000 && sampling_rate != 12000
&& sampling_rate != 16000 && sampling_rate != 24000
@@ -297,6 +319,21 @@
}
frame_size = sampling_rate/50;
+ channels = atoi(argv[args]);
+ args++;
+
+ if (channels < 1 || channels > 2)
+ {
+ fprintf(stderr, "Opus_demo supports only 1 or 2 channels.\n");
+ return EXIT_FAILURE;
+ }
+
+ if (!decode_only)
+ {
+ bitrate_bps = (opus_int32)atol(argv[args]);
+ args++;
+ }
+
/* defaults: */
use_vbr = 1;
bandwidth = OPUS_AUTO;
@@ -306,7 +343,7 @@
forcechannels = OPUS_AUTO;
use_dtx = 0;
packet_loss_perc = 0;
- max_frame_size = 960*6;
+ max_frame_size = 2*48000;
curr_read=0;
while( args < argc - 2 ) {
@@ -374,12 +411,19 @@
check_encoder_option(decode_only, "-cvbr");
cvbr = 1;
args++;
+ } else if( strcmp( argv[ args ], "-variable-duration" ) == 0 ) {
+ check_encoder_option(decode_only, "-variable-duration");
+ variable_duration = OPUS_FRAMESIZE_VARIABLE;
+ args++;
+ } else if( strcmp( argv[ args ], "-delayed-decision" ) == 0 ) {
+ check_encoder_option(decode_only, "-delayed-decision");
+ delayed_decision = 1;
+ args++;
} else if( strcmp( argv[ args ], "-dtx") == 0 ) {
check_encoder_option(decode_only, "-dtx");
use_dtx = 1;
args++;
} else if( strcmp( argv[ args ], "-loss" ) == 0 ) {
- check_decoder_option(encode_only, "-loss");
packet_loss_perc = atoi( argv[ args + 1 ] );
args += 2;
} else if( strcmp( argv[ args ], "-sweep" ) == 0 ) {
@@ -499,6 +543,7 @@
opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip));
opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16));
+ opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));
}
if (!encode_only)
{
@@ -554,6 +599,26 @@
if ( use_inbandfec ) {
data[1] = (unsigned char*)calloc(max_payload_bytes,sizeof(char));
}
+ if(delayed_decision)
+ {
+ if (variable_duration!=OPUS_FRAMESIZE_VARIABLE)
+ {
+ if (frame_size==sampling_rate/400)
+ variable_duration = OPUS_FRAMESIZE_2_5_MS;
+ else if (frame_size==sampling_rate/200)
+ variable_duration = OPUS_FRAMESIZE_5_MS;
+ else if (frame_size==sampling_rate/100)
+ variable_duration = OPUS_FRAMESIZE_10_MS;
+ else if (frame_size==sampling_rate/50)
+ variable_duration = OPUS_FRAMESIZE_20_MS;
+ else if (frame_size==sampling_rate/25)
+ variable_duration = OPUS_FRAMESIZE_40_MS;
+ else
+ variable_duration = OPUS_FRAMESIZE_60_MS;
+ opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));
+ }
+ frame_size = 2*48000;
+ }
while (!stop)
{
if (delayed_celt)
@@ -617,22 +682,28 @@
opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(mode_list[curr_mode][3]));
frame_size = mode_list[curr_mode][2];
}
- err = fread(fbytes, sizeof(short)*channels, frame_size, fin);
+ err = fread(fbytes, sizeof(short)*channels, frame_size-remaining, fin);
curr_read = err;
+ tot_in += curr_read;
for(i=0;i<curr_read*channels;i++)
{
opus_int32 s;
s=fbytes[2*i+1]<<8|fbytes[2*i];
s=((s&0xFFFF)^0x8000)-0x8000;
- in[i]=s;
+ in[i+remaining*channels]=s;
}
- if (curr_read < frame_size)
+ if (curr_read+remaining < frame_size)
{
- for (i=curr_read*channels;i<frame_size*channels;i++)
+ for (i=(curr_read+remaining)*channels;i<frame_size*channels;i++)
in[i] = 0;
- stop = 1;
+ if (encode_only || decode_only)
+ stop = 1;
}
len[toggle] = opus_encode(enc, in, frame_size, data[toggle], max_payload_bytes);
+ nb_encoded = opus_packet_get_samples_per_frame(data[toggle], sampling_rate)*opus_packet_get_nb_frames(data[toggle], len[toggle]);
+ remaining = frame_size-nb_encoded;
+ for(i=0;i<remaining*channels;i++)
+ in[i] = in[nb_encoded*channels+i];
if (sweep_bps!=0)
{
bitrate_bps += sweep_bps;
@@ -664,6 +735,18 @@
}
}
+#if 0 /* This is for testing the padding code, do not enable by default */
+ if (len[toggle]<1275)
+ {
+ int new_len = len[toggle]+rand()%(max_payload_bytes-len[toggle]);
+ if ((err = opus_packet_pad(data[toggle], len[toggle], new_len)) != OPUS_OK)
+ {
+ fprintf(stderr, "padding failed: %s\n", opus_strerror(err));
+ return EXIT_FAILURE;
+ }
+ len[toggle] = new_len;
+ }
+#endif
if (encode_only)
{
unsigned char int_field[4];
@@ -681,6 +764,7 @@
fprintf(stderr, "Error writing.\n");
return EXIT_FAILURE;
}
+ tot_samples += nb_encoded;
} else {
int output_samples;
lost = len[toggle]==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc);
@@ -705,6 +789,11 @@
}
if (output_samples>0)
{
+ if (!decode_only && tot_out + output_samples > tot_in)
+ {
+ stop=1;
+ output_samples = tot_in-tot_out;
+ }
if (output_samples>skip) {
int i;
for(i=0;i<(output_samples-skip)*channels;i++)
@@ -718,6 +807,7 @@
fprintf(stderr, "Error writing.\n");
return EXIT_FAILURE;
}
+ tot_out += output_samples-skip;
}
if (output_samples<skip) skip -= output_samples;
else skip = 0;
@@ -725,6 +815,7 @@
fprintf(stderr, "error decoding frame: %s\n",
opus_strerror(output_samples));
}
+ tot_samples += output_samples;
}
}
@@ -769,7 +860,7 @@
toggle = (toggle + use_inbandfec) & 1;
}
fprintf (stderr, "average bitrate: %7.3f kb/s\n",
- 1e-3*bits*sampling_rate/(frame_size*(double)count));
+ 1e-3*bits*sampling_rate/tot_samples);
fprintf (stderr, "maximum bitrate: %7.3f kb/s\n",
1e-3*bits_max*sampling_rate/frame_size);
if (!decode_only)