From 512d849c24b3ae708fb15c86a047c56d2591ab46 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin <jmvalin@jmvalin.ca> Date: Tue, 4 Dec 2012 14:13:46 -0500 Subject: [PATCH] Implements OPUS_GET_LAST_FRAME_DURATION decoder ctl() --- include/opus_defines.h | 11 ++++++++++- src/opus_decoder.c | 8 ++++++++ src/opus_demo.c | 10 +++++++--- src/opus_multistream_decoder.c | 2 ++ 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/include/opus_defines.h b/include/opus_defines.h index 94755f37c..cdde061a5 100644 --- a/include/opus_defines.h +++ b/include/opus_defines.h @@ -145,10 +145,14 @@ extern "C" { #define OPUS_GET_FINAL_RANGE_REQUEST 4031 #define OPUS_GET_PITCH_REQUEST 4033 #define OPUS_SET_GAIN_REQUEST 4034 -#define OPUS_GET_GAIN_REQUEST 4045 +#define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */ #define OPUS_SET_LSB_DEPTH_REQUEST 4036 #define OPUS_GET_LSB_DEPTH_REQUEST 4037 +#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039 + +/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */ + /* Macros to trigger compilation errors when the wrong types are provided to a CTL */ #define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x)) #define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr))) @@ -516,6 +520,11 @@ extern "C" { * 24 (default: 24). * @hideinitializer */ #define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x) + +/** Gets the duration (in samples) of the last packet successfully decoded or concealed. + * @param[out] x <tt>opus_int32 *</tt>: Number of samples (at current sampling rate). + * @hideinitializer */ +#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x) /**@}*/ /** @defgroup opus_genericctls Generic CTLs diff --git a/src/opus_decoder.c b/src/opus_decoder.c index 015ae17aa..67e8cdb54 100644 --- a/src/opus_decoder.c +++ b/src/opus_decoder.c @@ -64,6 +64,7 @@ struct OpusDecoder { int prev_mode; int frame_size; int prev_redundancy; + int last_packet_duration; opus_uint32 rangeFinal; }; @@ -813,6 +814,7 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, } if (packet_offset != NULL) *packet_offset = tot_offset; + st->last_packet_duration = nb_samples; return nb_samples; } @@ -966,6 +968,12 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) st->decode_gain = value; } break; + case OPUS_GET_LAST_PACKET_DURATION_REQUEST: + { + opus_uint32 *value = va_arg(ap, opus_uint32*); + *value = st->last_packet_duration; + } + break; default: /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/ ret = OPUS_UNIMPLEMENTED; diff --git a/src/opus_demo.c b/src/opus_demo.c index 1cb153a87..09b12a333 100644 --- a/src/opus_demo.c +++ b/src/opus_demo.c @@ -684,18 +684,22 @@ int main(int argc, char *argv[]) } else { int output_samples; lost = len[toggle]==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 */ - output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, max_frame_size, 1); + output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 1); } else { /* regular decode */ - output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, max_frame_size, 0); + output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, output_samples, 0); } } else { - output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, max_frame_size, 0); + output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 0); } if (output_samples>0) { diff --git a/src/opus_multistream_decoder.c b/src/opus_multistream_decoder.c index ed7cb5590..7564c7355 100644 --- a/src/opus_multistream_decoder.c +++ b/src/opus_multistream_decoder.c @@ -384,6 +384,8 @@ int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) { case OPUS_GET_BANDWIDTH_REQUEST: case OPUS_GET_SAMPLE_RATE_REQUEST: + case OPUS_GET_GAIN_REQUEST: + case OPUS_GET_LAST_PACKET_DURATION_REQUEST: { OpusDecoder *dec; /* For int32* GET params, just query the first stream */ -- GitLab