diff options
author | Jean-Marc Valin <jmvalin@amazon.com> | 2022-12-08 15:15:11 -0500 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@amazon.com> | 2022-12-08 15:15:11 -0500 |
commit | 217c22d5b2092de392e6453e611e82680fb7f430 (patch) | |
tree | bf87ca55ca968c215e64e142c020e191d7721951 /src | |
parent | 78b1e407b77f70ebfd8497b312ba4207398ed723 (diff) | |
download | opus-217c22d5b2092de392e6453e611e82680fb7f430.tar.gz |
Make FEC handling in opus_demo more general
Now only running the decoder on "received" packets
Diffstat (limited to 'src')
-rw-r--r-- | src/opus_demo.c | 111 |
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) |