Final range coder state now exposed through the ctl() interface
This commit is contained in:
parent
06cee2b1b4
commit
d48277374a
4 changed files with 59 additions and 54 deletions
24
src/opus.h
24
src/opus.h
|
@ -52,8 +52,9 @@ extern "C" {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define __check_int(x) (((void)((x) == (int)0)), (int)(x))
|
#define __check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
|
||||||
#define __check_int_ptr(ptr) ((ptr) + ((ptr) - (int*)(ptr)))
|
#define __check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr)))
|
||||||
|
#define __check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr)))
|
||||||
|
|
||||||
/* Error codes */
|
/* Error codes */
|
||||||
/** No error */
|
/** No error */
|
||||||
|
@ -132,10 +133,10 @@ extern "C" {
|
||||||
#define OPUS_GET_PACKET_LOSS_PERC_REQUEST 15
|
#define OPUS_GET_PACKET_LOSS_PERC_REQUEST 15
|
||||||
#define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __check_int_ptr(x)
|
#define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __check_int_ptr(x)
|
||||||
|
|
||||||
#define OPUS_SET_DTX_FLAG_REQUEST 16
|
#define OPUS_SET_DTX_REQUEST 16
|
||||||
#define OPUS_SET_DTX_FLAG(x) OPUS_SET_DTX_FLAG_REQUEST, __check_int(x)
|
#define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __check_int(x)
|
||||||
#define OPUS_GET_DTX_FLAG_REQUEST 17
|
#define OPUS_GET_DTX_REQUEST 17
|
||||||
#define OPUS_GET_DTX_FLAG(x) OPUS_GET_DTX_FLAG_REQUEST, __check_int_ptr(x)
|
#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __check_int_ptr(x)
|
||||||
|
|
||||||
#define OPUS_SET_VOICE_RATIO_REQUEST 18
|
#define OPUS_SET_VOICE_RATIO_REQUEST 18
|
||||||
#define OPUS_SET_VOICE_RATIO(x) OPUS_SET_VOICE_RATIO_REQUEST, __check_int(x)
|
#define OPUS_SET_VOICE_RATIO(x) OPUS_SET_VOICE_RATIO_REQUEST, __check_int(x)
|
||||||
|
@ -160,6 +161,11 @@ extern "C" {
|
||||||
#define OPUS_GET_LOOKAHEAD_REQUEST 27
|
#define OPUS_GET_LOOKAHEAD_REQUEST 27
|
||||||
#define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __check_int_ptr(x)
|
#define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __check_int_ptr(x)
|
||||||
|
|
||||||
|
/* For testing purposes: the encoder and decoder state should
|
||||||
|
always be identical after coding a payload */
|
||||||
|
#define OPUS_GET_FINAL_RANGE_REQUEST 29
|
||||||
|
#define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __check_uint_ptr(x)
|
||||||
|
|
||||||
typedef struct OpusEncoder OpusEncoder;
|
typedef struct OpusEncoder OpusEncoder;
|
||||||
typedef struct OpusDecoder OpusDecoder;
|
typedef struct OpusDecoder OpusDecoder;
|
||||||
|
|
||||||
|
@ -263,12 +269,6 @@ OPUS_EXPORT const char *opus_strerror(int error);
|
||||||
|
|
||||||
OPUS_EXPORT const char *opus_get_version_string(void);
|
OPUS_EXPORT const char *opus_get_version_string(void);
|
||||||
|
|
||||||
/* For testing purposes: the encoder and decoder state should
|
|
||||||
always be identical after coding a payload */
|
|
||||||
OPUS_EXPORT int opus_encoder_get_final_range(OpusEncoder *st);
|
|
||||||
OPUS_EXPORT int opus_decoder_get_final_range(OpusDecoder *st);
|
|
||||||
|
|
||||||
|
|
||||||
/* Repacketizer */
|
/* Repacketizer */
|
||||||
typedef struct OpusRepacketizer OpusRepacketizer;
|
typedef struct OpusRepacketizer OpusRepacketizer;
|
||||||
|
|
||||||
|
|
|
@ -724,10 +724,16 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
|
||||||
{
|
{
|
||||||
case OPUS_GET_BANDWIDTH_REQUEST:
|
case OPUS_GET_BANDWIDTH_REQUEST:
|
||||||
{
|
{
|
||||||
int *value = va_arg(ap, int*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->bandwidth;
|
*value = st->bandwidth;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case OPUS_GET_FINAL_RANGE_REQUEST:
|
||||||
|
{
|
||||||
|
opus_uint32 *value = va_arg(ap, opus_uint32*);
|
||||||
|
*value = st->rangeFinal;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);
|
fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);
|
||||||
break;
|
break;
|
||||||
|
@ -742,10 +748,6 @@ void opus_decoder_destroy(OpusDecoder *st)
|
||||||
free(st);
|
free(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
int opus_decoder_get_final_range(OpusDecoder *st)
|
|
||||||
{
|
|
||||||
return st->rangeFinal;
|
|
||||||
}
|
|
||||||
|
|
||||||
int opus_packet_get_bandwidth(const unsigned char *data)
|
int opus_packet_get_bandwidth(const unsigned char *data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -794,19 +794,19 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
{
|
{
|
||||||
case OPUS_SET_APPLICATION_REQUEST:
|
case OPUS_SET_APPLICATION_REQUEST:
|
||||||
{
|
{
|
||||||
int value = va_arg(ap, int);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
st->application = value;
|
st->application = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_GET_APPLICATION_REQUEST:
|
case OPUS_GET_APPLICATION_REQUEST:
|
||||||
{
|
{
|
||||||
int *value = va_arg(ap, int*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->mode;
|
*value = st->mode;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_SET_BITRATE_REQUEST:
|
case OPUS_SET_BITRATE_REQUEST:
|
||||||
{
|
{
|
||||||
int value = va_arg(ap, int);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
if (value != OPUS_BITRATE_AUTO)
|
if (value != OPUS_BITRATE_AUTO)
|
||||||
{
|
{
|
||||||
if (value <= 0)
|
if (value <= 0)
|
||||||
|
@ -819,25 +819,25 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
break;
|
break;
|
||||||
case OPUS_GET_BITRATE_REQUEST:
|
case OPUS_GET_BITRATE_REQUEST:
|
||||||
{
|
{
|
||||||
int *value = va_arg(ap, int*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->bitrate_bps;
|
*value = st->bitrate_bps;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_SET_FORCE_MONO_REQUEST:
|
case OPUS_SET_FORCE_MONO_REQUEST:
|
||||||
{
|
{
|
||||||
int value = va_arg(ap, int);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
st->force_mono = value;
|
st->force_mono = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_GET_FORCE_MONO_REQUEST:
|
case OPUS_GET_FORCE_MONO_REQUEST:
|
||||||
{
|
{
|
||||||
int *value = va_arg(ap, int*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = !!st->force_mono;
|
*value = !!st->force_mono;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_SET_BANDWIDTH_REQUEST:
|
case OPUS_SET_BANDWIDTH_REQUEST:
|
||||||
{
|
{
|
||||||
int value = va_arg(ap, int);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
if (value < OPUS_BANDWIDTH_AUTO || value > OPUS_BANDWIDTH_FULLBAND)
|
if (value < OPUS_BANDWIDTH_AUTO || value > OPUS_BANDWIDTH_FULLBAND)
|
||||||
return OPUS_BAD_ARG;
|
return OPUS_BAD_ARG;
|
||||||
st->user_bandwidth = value;
|
st->user_bandwidth = value;
|
||||||
|
@ -852,50 +852,50 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
break;
|
break;
|
||||||
case OPUS_GET_BANDWIDTH_REQUEST:
|
case OPUS_GET_BANDWIDTH_REQUEST:
|
||||||
{
|
{
|
||||||
int *value = va_arg(ap, int*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->bandwidth;
|
*value = st->bandwidth;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_SET_DTX_FLAG_REQUEST:
|
case OPUS_SET_DTX_REQUEST:
|
||||||
{
|
{
|
||||||
int value = va_arg(ap, int);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
st->silk_mode.useDTX = value;
|
st->silk_mode.useDTX = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_GET_DTX_FLAG_REQUEST:
|
case OPUS_GET_DTX_REQUEST:
|
||||||
{
|
{
|
||||||
int *value = va_arg(ap, int*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->silk_mode.useDTX;
|
*value = st->silk_mode.useDTX;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_SET_COMPLEXITY_REQUEST:
|
case OPUS_SET_COMPLEXITY_REQUEST:
|
||||||
{
|
{
|
||||||
int value = va_arg(ap, int);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
st->silk_mode.complexity = value;
|
st->silk_mode.complexity = value;
|
||||||
celt_encoder_ctl(celt_enc, CELT_SET_COMPLEXITY(value));
|
celt_encoder_ctl(celt_enc, CELT_SET_COMPLEXITY(value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_GET_COMPLEXITY_REQUEST:
|
case OPUS_GET_COMPLEXITY_REQUEST:
|
||||||
{
|
{
|
||||||
int *value = va_arg(ap, int*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->silk_mode.complexity;
|
*value = st->silk_mode.complexity;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_SET_INBAND_FEC_FLAG_REQUEST:
|
case OPUS_SET_INBAND_FEC_FLAG_REQUEST:
|
||||||
{
|
{
|
||||||
int value = va_arg(ap, int);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
st->silk_mode.useInBandFEC = value;
|
st->silk_mode.useInBandFEC = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_GET_INBAND_FEC_FLAG_REQUEST:
|
case OPUS_GET_INBAND_FEC_FLAG_REQUEST:
|
||||||
{
|
{
|
||||||
int *value = va_arg(ap, int*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->silk_mode.useInBandFEC;
|
*value = st->silk_mode.useInBandFEC;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
|
case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
|
||||||
{
|
{
|
||||||
int value = va_arg(ap, int);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
if (value < 0 || value > 100)
|
if (value < 0 || value > 100)
|
||||||
return OPUS_BAD_ARG;
|
return OPUS_BAD_ARG;
|
||||||
st->silk_mode.packetLossPercentage = value;
|
st->silk_mode.packetLossPercentage = value;
|
||||||
|
@ -904,26 +904,26 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
break;
|
break;
|
||||||
case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
|
case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
|
||||||
{
|
{
|
||||||
int *value = va_arg(ap, int*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->silk_mode.packetLossPercentage;
|
*value = st->silk_mode.packetLossPercentage;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_SET_VBR_REQUEST:
|
case OPUS_SET_VBR_REQUEST:
|
||||||
{
|
{
|
||||||
int value = va_arg(ap, int);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
st->use_vbr = value;
|
st->use_vbr = value;
|
||||||
st->silk_mode.useCBR = 1-value;
|
st->silk_mode.useCBR = 1-value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_GET_VBR_REQUEST:
|
case OPUS_GET_VBR_REQUEST:
|
||||||
{
|
{
|
||||||
int *value = va_arg(ap, int*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->use_vbr;
|
*value = st->use_vbr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_SET_VOICE_RATIO_REQUEST:
|
case OPUS_SET_VOICE_RATIO_REQUEST:
|
||||||
{
|
{
|
||||||
int value = va_arg(ap, int);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
if (value>100 || value<0)
|
if (value>100 || value<0)
|
||||||
goto bad_arg;
|
goto bad_arg;
|
||||||
st->voice_ratio = value;
|
st->voice_ratio = value;
|
||||||
|
@ -931,40 +931,46 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
break;
|
break;
|
||||||
case OPUS_GET_VOICE_RATIO_REQUEST:
|
case OPUS_GET_VOICE_RATIO_REQUEST:
|
||||||
{
|
{
|
||||||
int *value = va_arg(ap, int*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->voice_ratio;
|
*value = st->voice_ratio;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_SET_VBR_CONSTRAINT_REQUEST:
|
case OPUS_SET_VBR_CONSTRAINT_REQUEST:
|
||||||
{
|
{
|
||||||
int value = va_arg(ap, int);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
st->vbr_constraint = value;
|
st->vbr_constraint = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_GET_VBR_CONSTRAINT_REQUEST:
|
case OPUS_GET_VBR_CONSTRAINT_REQUEST:
|
||||||
{
|
{
|
||||||
int *value = va_arg(ap, int*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->vbr_constraint;
|
*value = st->vbr_constraint;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_SET_SIGNAL_REQUEST:
|
case OPUS_SET_SIGNAL_REQUEST:
|
||||||
{
|
{
|
||||||
int value = va_arg(ap, int);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
st->signal_type = value;
|
st->signal_type = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_GET_SIGNAL_REQUEST:
|
case OPUS_GET_SIGNAL_REQUEST:
|
||||||
{
|
{
|
||||||
int *value = va_arg(ap, int*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->signal_type;
|
*value = st->signal_type;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_GET_LOOKAHEAD_REQUEST:
|
case OPUS_GET_LOOKAHEAD_REQUEST:
|
||||||
{
|
{
|
||||||
int *value = va_arg(ap, int*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->delay_compensation+st->Fs/400;
|
*value = st->delay_compensation+st->Fs/400;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case OPUS_GET_FINAL_RANGE_REQUEST:
|
||||||
|
{
|
||||||
|
opus_uint32 *value = va_arg(ap, opus_uint32*);
|
||||||
|
*value = st->rangeFinal;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);
|
fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);
|
||||||
break;
|
break;
|
||||||
|
@ -980,8 +986,3 @@ void opus_encoder_destroy(OpusEncoder *st)
|
||||||
{
|
{
|
||||||
free(st);
|
free(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
int opus_encoder_get_final_range(OpusEncoder *st)
|
|
||||||
{
|
|
||||||
return st->rangeFinal;
|
|
||||||
}
|
|
||||||
|
|
|
@ -111,7 +111,8 @@ int main(int argc, char *argv[])
|
||||||
const char *bandwidth_string;
|
const char *bandwidth_string;
|
||||||
int lost = 0, lost_prev = 1;
|
int lost = 0, lost_prev = 1;
|
||||||
int toggle = 0;
|
int toggle = 0;
|
||||||
int enc_final_range[2];
|
opus_uint32 enc_final_range[2];
|
||||||
|
opus_uint32 dec_final_range;
|
||||||
int encode_only=0, decode_only=0;
|
int encode_only=0, decode_only=0;
|
||||||
|
|
||||||
if (argc < 7 )
|
if (argc < 7 )
|
||||||
|
@ -275,7 +276,7 @@ int main(int argc, char *argv[])
|
||||||
opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
|
opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
|
||||||
opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC_FLAG(use_inbandfec));
|
opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC_FLAG(use_inbandfec));
|
||||||
opus_encoder_ctl(enc, OPUS_SET_FORCE_MONO(forcemono));
|
opus_encoder_ctl(enc, OPUS_SET_FORCE_MONO(forcemono));
|
||||||
opus_encoder_ctl(enc, OPUS_SET_DTX_FLAG(use_dtx));
|
opus_encoder_ctl(enc, OPUS_SET_DTX(use_dtx));
|
||||||
opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc));
|
opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc));
|
||||||
|
|
||||||
skip = 5*sampling_rate/1000;
|
skip = 5*sampling_rate/1000;
|
||||||
|
@ -349,7 +350,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
len[toggle] = opus_encode(enc, in, frame_size, data[toggle], max_payload_bytes);
|
len[toggle] = opus_encode(enc, in, frame_size, data[toggle], max_payload_bytes);
|
||||||
enc_final_range[toggle] = opus_encoder_get_final_range( enc );
|
opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range[toggle]));
|
||||||
if (len[toggle] < 0)
|
if (len[toggle] < 0)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "opus_encode() returned %d\n", len[toggle]);
|
fprintf (stderr, "opus_encode() returned %d\n", len[toggle]);
|
||||||
|
@ -391,10 +392,11 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));
|
||||||
/* compare final range encoder rng values of encoder and decoder */
|
/* compare final range encoder rng values of encoder and decoder */
|
||||||
if( enc_final_range[toggle^use_inbandfec]!=0 && !encode_only && !lost && !lost_prev &&
|
if( enc_final_range[toggle^use_inbandfec]!=0 && !encode_only && !lost && !lost_prev &&
|
||||||
opus_decoder_get_final_range( dec ) != enc_final_range[toggle^use_inbandfec] ) {
|
dec_final_range != enc_final_range[toggle^use_inbandfec] ) {
|
||||||
fprintf (stderr, "Error: Range coder state mismatch between encoder and decoder in frame %d: 0x%8x vs 0x%8x\n", count, enc_final_range[toggle^use_inbandfec], opus_decoder_get_final_range( dec ));
|
fprintf (stderr, "Error: Range coder state mismatch between encoder and decoder in frame %d: 0x%8x vs 0x%8x\n", count, enc_final_range[toggle^use_inbandfec], dec_final_range);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue