diff --git a/webrtc/modules/audio_coding/codecs/opus/opus_interface.c b/webrtc/modules/audio_coding/codecs/opus/opus_interface.c index d79a9ad290..aff089f092 100644 --- a/webrtc/modules/audio_coding/codecs/opus/opus_interface.c +++ b/webrtc/modules/audio_coding/codecs/opus/opus_interface.c @@ -208,6 +208,20 @@ int16_t WebRtcOpus_SetComplexity(OpusEncInst* inst, int32_t complexity) { } } +int16_t WebRtcOpus_SetForceChannels(OpusEncInst* inst, int32_t num_channels) { + if (!inst) + return -1; + if (num_channels == 0) { + return opus_encoder_ctl(inst->encoder, + OPUS_SET_FORCE_CHANNELS(OPUS_AUTO)); + } else if (num_channels == 1 || num_channels == 2) { + return opus_encoder_ctl(inst->encoder, + OPUS_SET_FORCE_CHANNELS(num_channels)); + } else { + return -1; + } +} + int16_t WebRtcOpus_DecoderCreate(OpusDecInst** inst, size_t channels) { int error; OpusDecInst* state; diff --git a/webrtc/modules/audio_coding/codecs/opus/opus_interface.h b/webrtc/modules/audio_coding/codecs/opus/opus_interface.h index 754b49c808..d3c314e25a 100644 --- a/webrtc/modules/audio_coding/codecs/opus/opus_interface.h +++ b/webrtc/modules/audio_coding/codecs/opus/opus_interface.h @@ -195,6 +195,28 @@ int16_t WebRtcOpus_DisableDtx(OpusEncInst* inst); */ int16_t WebRtcOpus_SetComplexity(OpusEncInst* inst, int32_t complexity); +/* + * WebRtcOpus_SetForceChannels(...) + * + * If the encoder is initialized as a stereo encoder, Opus will by default + * decide whether to encode in mono or stereo based on the bitrate. This + * function overrules the previous setting, and forces the encoder to encode + * in auto/mono/stereo. + * + * If the Encoder is initialized as a mono encoder, and one tries to force + * stereo, the function will return an error. + * + * Input: + * - inst : Encoder context + * - num_channels : 0 - Not forced + * 1 - Mono + * 2 - Stereo + * + * Return value : 0 - Success + * -1 - Error + */ +int16_t WebRtcOpus_SetForceChannels(OpusEncInst* inst, int32_t num_channels); + int16_t WebRtcOpus_DecoderCreate(OpusDecInst** inst, size_t channels); int16_t WebRtcOpus_DecoderFree(OpusDecInst* inst); diff --git a/webrtc/modules/audio_coding/codecs/opus/opus_unittest.cc b/webrtc/modules/audio_coding/codecs/opus/opus_unittest.cc index c634885e52..84b27979b2 100644 --- a/webrtc/modules/audio_coding/codecs/opus/opus_unittest.cc +++ b/webrtc/modules/audio_coding/codecs/opus/opus_unittest.cc @@ -409,6 +409,27 @@ TEST_P(OpusTest, OpusSetComplexity) { EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); } +TEST_P(OpusTest, OpusForceChannels) { + // Test without creating encoder memory. + EXPECT_EQ(-1, WebRtcOpus_SetForceChannels(opus_encoder_, 1)); + + ASSERT_EQ(0, + WebRtcOpus_EncoderCreate(&opus_encoder_, channels_, application_)); + + if (channels_ == 2) { + EXPECT_EQ(-1, WebRtcOpus_SetForceChannels(opus_encoder_, 3)); + EXPECT_EQ(0, WebRtcOpus_SetForceChannels(opus_encoder_, 2)); + EXPECT_EQ(0, WebRtcOpus_SetForceChannels(opus_encoder_, 1)); + EXPECT_EQ(0, WebRtcOpus_SetForceChannels(opus_encoder_, 0)); + } else { + EXPECT_EQ(-1, WebRtcOpus_SetForceChannels(opus_encoder_, 2)); + EXPECT_EQ(0, WebRtcOpus_SetForceChannels(opus_encoder_, 1)); + EXPECT_EQ(0, WebRtcOpus_SetForceChannels(opus_encoder_, 0)); + } + + EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); +} + // Encode and decode one frame, initialize the decoder and // decode once more. TEST_P(OpusTest, OpusDecodeInit) {