ref: 512d849c24b3ae708fb15c86a047c56d2591ab46
parent: a5bd4409319614f166a83934baddceed7e6c58b4
author: Jean-Marc Valin <[email protected]>
date: Tue Dec 4 09:13:46 EST 2012
Implements OPUS_GET_LAST_FRAME_DURATION decoder ctl()
--- a/include/opus_defines.h
+++ b/include/opus_defines.h
@@ -145,10 +145,14 @@
#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 @@
* 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
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -64,6 +64,7 @@
int prev_mode;
int frame_size;
int prev_redundancy;
+ int last_packet_duration;
opus_uint32 rangeFinal;
};
@@ -813,6 +814,7 @@
}
if (packet_offset != NULL)
*packet_offset = tot_offset;
+ st->last_packet_duration = nb_samples;
return nb_samples;
}
@@ -964,6 +966,12 @@
break;
}
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:
--- a/src/opus_demo.c
+++ b/src/opus_demo.c
@@ -684,18 +684,22 @@
} 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)
{
--- a/src/opus_multistream_decoder.c
+++ b/src/opus_multistream_decoder.c
@@ -384,6 +384,8 @@
{
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 */