summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@amazon.com>2022-12-08 15:15:11 -0500
committerJean-Marc Valin <jmvalin@amazon.com>2022-12-08 15:15:11 -0500
commit217c22d5b2092de392e6453e611e82680fb7f430 (patch)
treebf87ca55ca968c215e64e142c020e191d7721951
parent78b1e407b77f70ebfd8497b312ba4207398ed723 (diff)
downloadopus-217c22d5b2092de392e6453e611e82680fb7f430.tar.gz
Make FEC handling in opus_demo more general
Now only running the decoder on "received" packets
-rw-r--r--src/opus_demo.c111
1 files changed, 56 insertions, 55 deletions
diff --git a/src/opus_demo.c b/src/opus_demo.c
index 4cc26a6c..3301df2e 100644
--- a/src/opus_demo.c
+++ b/src/opus_demo.c
@@ -216,10 +216,10 @@ int main(int argc, char *argv[])
OpusEncoder *enc=NULL;
OpusDecoder *dec=NULL;
int args;
- int len[2];
+ int len;
int frame_size, channels;
opus_int32 bitrate_bps=0;
- unsigned char *data[2] = {NULL, NULL};
+ unsigned char *data = NULL;
unsigned char *fbytes=NULL;
opus_int32 sampling_rate;
int use_vbr;
@@ -243,8 +243,7 @@ int main(int argc, char *argv[])
int bandwidth=OPUS_AUTO;
const char *bandwidth_string;
int lost = 0, lost_prev = 1;
- int toggle = 0;
- opus_uint32 enc_final_range[2];
+ opus_uint32 enc_final_range;
opus_uint32 dec_final_range;
int encode_only=0, decode_only=0;
int max_frame_size = 48000*2;
@@ -264,6 +263,7 @@ int main(int argc, char *argv[])
int variable_duration=OPUS_FRAMESIZE_ARG;
int delayed_decision=0;
int ret = EXIT_FAILURE;
+ int lost_count=0;
if (argc < 5 )
{
@@ -587,10 +587,7 @@ int main(int argc, char *argv[])
out = (short*)malloc(max_frame_size*channels*sizeof(short));
/* We need to allocate for 16-bit PCM data, but we store it as unsigned char. */
fbytes = (unsigned char*)malloc(max_frame_size*channels*sizeof(short));
- data[0] = (unsigned char*)calloc(max_payload_bytes,sizeof(unsigned char));
- if ( use_inbandfec ) {
- data[1] = (unsigned char*)calloc(max_payload_bytes,sizeof(unsigned char));
- }
+ data = (unsigned char*)calloc(max_payload_bytes,sizeof(unsigned char));
if(delayed_decision)
{
if (frame_size==sampling_rate/400)
@@ -652,22 +649,22 @@ int main(int argc, char *argv[])
num_read = fread(ch, 1, 4, fin);
if (num_read!=4)
break;
- len[toggle] = char_to_int(ch);
- if (len[toggle]>max_payload_bytes || len[toggle]<0)
+ len = char_to_int(ch);
+ if (len>max_payload_bytes || len<0)
{
- fprintf(stderr, "Invalid payload length: %d\n",len[toggle]);
+ fprintf(stderr, "Invalid payload length: %d\n",len);
break;
}
num_read = fread(ch, 1, 4, fin);
if (num_read!=4)
break;
- enc_final_range[toggle] = char_to_int(ch);
- num_read = fread(data[toggle], 1, len[toggle], fin);
- if (num_read!=(size_t)len[toggle])
+ enc_final_range = char_to_int(ch);
+ num_read = fread(data, 1, len, fin);
+ if (num_read!=(size_t)len)
{
fprintf(stderr, "Ran out of input, "
"expecting %d bytes got %d\n",
- len[toggle],(int)num_read);
+ len,(int)num_read);
break;
}
} else {
@@ -696,8 +693,8 @@ int main(int argc, char *argv[])
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]);
+ len = opus_encode(enc, in, frame_size, data, max_payload_bytes);
+ nb_encoded = opus_packet_get_samples_per_frame(data, sampling_rate)*opus_packet_get_nb_frames(data, len);
remaining = frame_size-nb_encoded;
for(i=0;i<remaining*channels;i++)
in[i] = in[nb_encoded*channels+i];
@@ -716,10 +713,10 @@ int main(int argc, char *argv[])
bitrate_bps = 1000;
opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
}
- opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range[toggle]));
- if (len[toggle] < 0)
+ opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range));
+ if (len < 0)
{
- fprintf (stderr, "opus_encode() returned %d\n", len[toggle]);
+ fprintf (stderr, "opus_encode() returned %d\n", len);
goto failure;
}
curr_mode_count += frame_size;
@@ -731,56 +728,60 @@ int main(int argc, char *argv[])
}
#if 0 /* This is for testing the padding code, do not enable by default */
- if (len[toggle]<1275)
+ if (len<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)
+ int new_len = len+rand()%(max_payload_bytes-len);
+ if ((err = opus_packet_pad(data, len, new_len)) != OPUS_OK)
{
fprintf(stderr, "padding failed: %s\n", opus_strerror(err));
goto failure;
}
- len[toggle] = new_len;
+ len = new_len;
}
#endif
if (encode_only)
{
unsigned char int_field[4];
- int_to_char(len[toggle], int_field);
+ int_to_char(len, int_field);
if (fwrite(int_field, 1, 4, fout) != 4) {
fprintf(stderr, "Error writing.\n");
goto failure;
}
- int_to_char(enc_final_range[toggle], int_field);
+ int_to_char(enc_final_range, int_field);
if (fwrite(int_field, 1, 4, fout) != 4) {
fprintf(stderr, "Error writing.\n");
goto failure;
}
- if (fwrite(data[toggle], 1, len[toggle], fout) != (unsigned)len[toggle]) {
+ if (fwrite(data, 1, len, fout) != (unsigned)len) {
fprintf(stderr, "Error writing.\n");
goto failure;
}
tot_samples += nb_encoded;
} else {
- opus_int32 output_samples;
- lost = len[toggle]==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc);
+ int fr;
+ int run_decoder;
+ lost = len==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc);
if (lost)
- opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
- else
- output_samples = max_frame_size;
- if( count >= use_inbandfec ) {
- /* delay by one packet when using in-band FEC */
- if( use_inbandfec ) {
- if( lost_prev ) {
- /* attempt to decode with in-band FEC from next packet */
- opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
- output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 1);
- } else {
- /* regular decode */
- output_samples = max_frame_size;
- output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, output_samples, 0);
- }
+ {
+ lost_count++;
+ run_decoder = 0;
+ } else {
+ run_decoder= 1;
+ }
+ if (run_decoder)
+ run_decoder += lost_count;
+ /* FIXME: Figure out how to trigger the decoder when the last packet of the file is lost. */
+ for (fr=0;fr<run_decoder;fr++) {
+ opus_int32 output_samples=0;
+ if (fr < lost_count-1) {
+ opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
+ output_samples = opus_decode(dec, NULL, 0, out, output_samples, 1);
+ } else if (fr == lost_count-1) {
+ opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
+ output_samples = opus_decode(dec, data, len, out, output_samples, 1);
} else {
- output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 0);
+ output_samples = max_frame_size;
+ output_samples = opus_decode(dec, data, len, out, output_samples, 0);
}
if (output_samples>0)
{
@@ -817,24 +818,26 @@ int main(int argc, char *argv[])
if (!encode_only)
opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));
/* compare final range encoder rng values of encoder and decoder */
- if( enc_final_range[toggle^use_inbandfec]!=0 && !encode_only
+ if( enc_final_range!=0 && !encode_only
&& !lost && !lost_prev
- && dec_final_range != enc_final_range[toggle^use_inbandfec] ) {
+ && dec_final_range != enc_final_range ) {
fprintf (stderr, "Error: Range coder state mismatch "
"between encoder and decoder "
"in frame %ld: 0x%8lx vs 0x%8lx\n",
(long)count,
- (unsigned long)enc_final_range[toggle^use_inbandfec],
+ (unsigned long)enc_final_range,
(unsigned long)dec_final_range);
goto failure;
}
lost_prev = lost;
+ if (!lost)
+ lost_count = 0;
if( count >= use_inbandfec ) {
/* count bits */
- bits += len[toggle]*8;
- bits_max = ( len[toggle]*8 > bits_max ) ? len[toggle]*8 : bits_max;
- bits2 += len[toggle]*len[toggle]*64;
+ bits += len*8;
+ bits_max = ( len*8 > bits_max ) ? len*8 : bits_max;
+ bits2 += len*len*64;
if (!decode_only)
{
nrg = 0.0;
@@ -843,13 +846,12 @@ int main(int argc, char *argv[])
}
nrg /= frame_size * channels;
if( nrg > 1e5 ) {
- bits_act += len[toggle]*8;
+ bits_act += len*8;
count_act++;
}
}
}
count++;
- toggle = (toggle + use_inbandfec) & 1;
}
if(decode_only && count > 0)
@@ -879,8 +881,7 @@ int main(int argc, char *argv[])
failure:
opus_encoder_destroy(enc);
opus_decoder_destroy(dec);
- free(data[0]);
- free(data[1]);
+ free(data);
if (fin)
fclose(fin);
if (fout)