diff --git a/webrtc/modules/audio_coding/codecs/audio_decoder.h b/webrtc/modules/audio_coding/codecs/audio_decoder.h index 22e44a448..1ac02c50f 100644 --- a/webrtc/modules/audio_coding/codecs/audio_decoder.h +++ b/webrtc/modules/audio_coding/codecs/audio_decoder.h @@ -31,8 +31,8 @@ class AudioDecoder { // Used by PacketDuration below. Save the value -1 for errors. enum { kNotImplemented = -2 }; - AudioDecoder() : channels_(1) {} - virtual ~AudioDecoder() {} + AudioDecoder() = default; + virtual ~AudioDecoder() = default; // Decodes |encode_len| bytes from |encoded| and writes the result in // |decoded|. The maximum bytes allowed to be written into |decoded| is @@ -97,7 +97,7 @@ class AudioDecoder { // isn't a CNG decoder, don't call this method. virtual CNG_dec_inst* CngDecoderInstance(); - size_t channels() const { return channels_; } + virtual size_t Channels() const = 0; protected: static SpeechType ConvertSpeechType(int16_t type); @@ -114,8 +114,6 @@ class AudioDecoder { int16_t* decoded, SpeechType* speech_type); - size_t channels_; - private: DISALLOW_COPY_AND_ASSIGN(AudioDecoder); }; diff --git a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h index 6b197bc2d..077568a1c 100644 --- a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h +++ b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h @@ -81,6 +81,7 @@ class AudioEncoderDecoderIsacT : public AudioEncoder, public AudioDecoder { uint32_t rtp_timestamp, uint32_t arrival_timestamp) override; int ErrorCode() override; + size_t Channels() const override { return 1; } protected: // AudioEncoder protected method. diff --git a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc index cf407dbed..2fc43061e 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc +++ b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc @@ -121,7 +121,6 @@ AudioDecoderProxy::AudioDecoderProxy() void AudioDecoderProxy::SetDecoder(AudioDecoder* decoder) { CriticalSectionScoped decoder_lock(decoder_lock_.get()); decoder_ = decoder; - channels_ = decoder->channels(); CHECK_EQ(decoder_->Init(), 0); } @@ -205,6 +204,11 @@ CNG_dec_inst* AudioDecoderProxy::CngDecoderInstance() { return decoder_->CngDecoderInstance(); } +size_t AudioDecoderProxy::Channels() const { + CriticalSectionScoped decoder_lock(decoder_lock_.get()); + return decoder_->Channels(); +} + int16_t ACMGenericCodec::EncoderParams(WebRtcACMCodecParams* enc_params) { *enc_params = acm_codec_params_; return 0; diff --git a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h index 93fda43b8..cf07ea4db 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h +++ b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h @@ -73,6 +73,7 @@ class AudioDecoderProxy final : public AudioDecoder { size_t encoded_len) const override; bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const override; CNG_dec_inst* CngDecoderInstance() override; + size_t Channels() const override; private: rtc::scoped_ptr decoder_lock_; diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc index 8ffb761d0..ce24e4a7e 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc +++ b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc @@ -54,7 +54,7 @@ int AudioDecoderPcmU::DecodeInternal(const uint8_t* encoded, int AudioDecoderPcmU::PacketDuration(const uint8_t* encoded, size_t encoded_len) const { // One encoded byte per sample per channel. - return static_cast(encoded_len / channels_); + return static_cast(encoded_len / Channels()); } // PCMa @@ -74,7 +74,7 @@ int AudioDecoderPcmA::DecodeInternal(const uint8_t* encoded, int AudioDecoderPcmA::PacketDuration(const uint8_t* encoded, size_t encoded_len) const { // One encoded byte per sample per channel. - return static_cast(encoded_len / channels_); + return static_cast(encoded_len / Channels()); } // PCM16B @@ -98,12 +98,12 @@ int AudioDecoderPcm16B::DecodeInternal(const uint8_t* encoded, int AudioDecoderPcm16B::PacketDuration(const uint8_t* encoded, size_t encoded_len) const { // Two encoded byte per sample per channel. - return static_cast(encoded_len / (2 * channels_)); + return static_cast(encoded_len / (2 * Channels())); } -AudioDecoderPcm16BMultiCh::AudioDecoderPcm16BMultiCh(int num_channels) { +AudioDecoderPcm16BMultiCh::AudioDecoderPcm16BMultiCh(int num_channels) + : channels_(num_channels) { DCHECK(num_channels > 0); - channels_ = num_channels; } #endif @@ -171,11 +171,10 @@ int AudioDecoderG722::Init() { int AudioDecoderG722::PacketDuration(const uint8_t* encoded, size_t encoded_len) const { // 1/2 encoded byte per sample per channel. - return static_cast(2 * encoded_len / channels_); + return static_cast(2 * encoded_len / Channels()); } AudioDecoderG722Stereo::AudioDecoderG722Stereo() { - channels_ = 2; WebRtcG722_CreateDecoder(&dec_state_left_); WebRtcG722_CreateDecoder(&dec_state_right_); } @@ -260,9 +259,8 @@ void AudioDecoderG722Stereo::SplitStereoPacket(const uint8_t* encoded, // Opus #ifdef WEBRTC_CODEC_OPUS -AudioDecoderOpus::AudioDecoderOpus(int num_channels) { +AudioDecoderOpus::AudioDecoderOpus(int num_channels) : channels_(num_channels) { DCHECK(num_channels == 1 || num_channels == 2); - channels_ = num_channels; WebRtcOpus_DecoderCreate(&dec_state_, static_cast(channels_)); } diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h index 2222b6277..5f9c35be5 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h +++ b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h @@ -39,6 +39,7 @@ class AudioDecoderPcmU : public AudioDecoder { AudioDecoderPcmU() {} virtual int Init() { return 0; } virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const; + size_t Channels() const override { return 1; } protected: int DecodeInternal(const uint8_t* encoded, @@ -56,6 +57,7 @@ class AudioDecoderPcmA : public AudioDecoder { AudioDecoderPcmA() {} virtual int Init() { return 0; } virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const; + size_t Channels() const override { return 1; } protected: int DecodeInternal(const uint8_t* encoded, @@ -70,23 +72,27 @@ class AudioDecoderPcmA : public AudioDecoder { class AudioDecoderPcmUMultiCh : public AudioDecoderPcmU { public: - explicit AudioDecoderPcmUMultiCh(size_t channels) : AudioDecoderPcmU() { + explicit AudioDecoderPcmUMultiCh(size_t channels) + : AudioDecoderPcmU(), channels_(channels) { assert(channels > 0); - channels_ = channels; } + size_t Channels() const override { return channels_; } private: + const size_t channels_; DISALLOW_COPY_AND_ASSIGN(AudioDecoderPcmUMultiCh); }; class AudioDecoderPcmAMultiCh : public AudioDecoderPcmA { public: - explicit AudioDecoderPcmAMultiCh(size_t channels) : AudioDecoderPcmA() { + explicit AudioDecoderPcmAMultiCh(size_t channels) + : AudioDecoderPcmA(), channels_(channels) { assert(channels > 0); - channels_ = channels; } + size_t Channels() const override { return channels_; } private: + const size_t channels_; DISALLOW_COPY_AND_ASSIGN(AudioDecoderPcmAMultiCh); }; @@ -98,6 +104,7 @@ class AudioDecoderPcm16B : public AudioDecoder { AudioDecoderPcm16B(); virtual int Init() { return 0; } virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const; + size_t Channels() const override { return 1; } protected: int DecodeInternal(const uint8_t* encoded, @@ -116,8 +123,10 @@ class AudioDecoderPcm16B : public AudioDecoder { class AudioDecoderPcm16BMultiCh : public AudioDecoderPcm16B { public: explicit AudioDecoderPcm16BMultiCh(int num_channels); + size_t Channels() const override { return channels_; } private: + const size_t channels_; DISALLOW_COPY_AND_ASSIGN(AudioDecoderPcm16BMultiCh); }; #endif @@ -130,6 +139,7 @@ class AudioDecoderIlbc : public AudioDecoder { virtual bool HasDecodePlc() const { return true; } virtual int DecodePlc(int num_frames, int16_t* decoded); virtual int Init(); + size_t Channels() const override { return 1; } protected: int DecodeInternal(const uint8_t* encoded, @@ -152,6 +162,7 @@ class AudioDecoderG722 : public AudioDecoder { virtual bool HasDecodePlc() const { return false; } virtual int Init(); virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const; + size_t Channels() const override { return 1; } protected: int DecodeInternal(const uint8_t* encoded, @@ -177,6 +188,7 @@ class AudioDecoderG722Stereo : public AudioDecoder { int sample_rate_hz, int16_t* decoded, SpeechType* speech_type) override; + size_t Channels() const override { return 2; } private: // Splits the stereo-interleaved payload in |encoded| into separate payloads @@ -205,6 +217,7 @@ class AudioDecoderOpus : public AudioDecoder { virtual int PacketDurationRedundant(const uint8_t* encoded, size_t encoded_len) const; virtual bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const; + size_t Channels() const override { return channels_; } protected: int DecodeInternal(const uint8_t* encoded, @@ -220,6 +233,7 @@ class AudioDecoderOpus : public AudioDecoder { private: OpusDecInst* dec_state_; + const size_t channels_; DISALLOW_COPY_AND_ASSIGN(AudioDecoderOpus); }; #endif @@ -242,6 +256,7 @@ class AudioDecoderCng : public AudioDecoder { uint32_t arrival_timestamp) { return -1; } CNG_dec_inst* CngDecoderInstance() override { return dec_state_; } + size_t Channels() const override { return 1; } protected: int DecodeInternal(const uint8_t* encoded, diff --git a/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h b/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h index b113e4af1..93261ab60 100644 --- a/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h +++ b/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h @@ -31,6 +31,7 @@ class MockAudioDecoder : public AudioDecoder { MOCK_METHOD5(IncomingPacket, int(const uint8_t*, size_t, uint16_t, uint32_t, uint32_t)); MOCK_METHOD0(ErrorCode, int()); + MOCK_CONST_METHOD0(Channels, size_t()); MOCK_CONST_METHOD0(codec_type, NetEqDecoder()); MOCK_METHOD1(CodecSupported, bool(NetEqDecoder)); }; diff --git a/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h b/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h index beff6ae61..d8c88561a 100644 --- a/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h +++ b/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h @@ -41,6 +41,7 @@ class ExternalPcm16B : public AudioDecoder { *speech_type = ConvertSpeechType(1); return ret; } + size_t Channels() const override { return 1; } private: DISALLOW_COPY_AND_ASSIGN(ExternalPcm16B); diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl.cc b/webrtc/modules/audio_coding/neteq/neteq_impl.cc index fb9656bf5..32c66295e 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_impl.cc +++ b/webrtc/modules/audio_coding/neteq/neteq_impl.cc @@ -644,8 +644,8 @@ int NetEqImpl::InsertPacketInternal(const WebRtcRTPHeader& rtp_header, decoder_database_->GetDecoderInfo(payload_type); assert(decoder_info); if (decoder_info->fs_hz != fs_hz_ || - decoder->channels() != algorithm_buffer_->Channels()) - SetSampleRateAndChannels(decoder_info->fs_hz, decoder->channels()); + decoder->Channels() != algorithm_buffer_->Channels()) + SetSampleRateAndChannels(decoder_info->fs_hz, decoder->Channels()); } // TODO(hlundin): Move this code to DelayManager class. @@ -1153,9 +1153,9 @@ int NetEqImpl::Decode(PacketList* packet_list, Operations* operation, // If sampling rate or number of channels has changed, we need to make // a reset. if (decoder_info->fs_hz != fs_hz_ || - decoder->channels() != algorithm_buffer_->Channels()) { + decoder->Channels() != algorithm_buffer_->Channels()) { // TODO(tlegrand): Add unittest to cover this event. - SetSampleRateAndChannels(decoder_info->fs_hz, decoder->channels()); + SetSampleRateAndChannels(decoder_info->fs_hz, decoder->Channels()); } sync_buffer_->set_end_timestamp(timestamp_); playout_timestamp_ = timestamp_; @@ -1219,7 +1219,7 @@ int NetEqImpl::Decode(PacketList* packet_list, Operations* operation, // since in this case, the we will increment the CNGplayedTS counter. // Increase with number of samples per channel. assert(*decoded_length == 0 || - (decoder && decoder->channels() == sync_buffer_->Channels())); + (decoder && decoder->Channels() == sync_buffer_->Channels())); sync_buffer_->IncreaseEndTimestamp( *decoded_length / static_cast(sync_buffer_->Channels())); } @@ -1239,8 +1239,8 @@ int NetEqImpl::DecodeLoop(PacketList* packet_list, Operations* operation, assert(decoder); // At this point, we must have a decoder object. // The number of channels in the |sync_buffer_| should be the same as the // number decoder channels. - assert(sync_buffer_->Channels() == decoder->channels()); - assert(decoded_buffer_length_ >= kMaxFrameSize * decoder->channels()); + assert(sync_buffer_->Channels() == decoder->Channels()); + assert(decoded_buffer_length_ >= kMaxFrameSize * decoder->Channels()); assert(*operation == kNormal || *operation == kAccelerate || *operation == kMerge || *operation == kPreemptiveExpand); packet_list->pop_front(); @@ -1254,8 +1254,9 @@ int NetEqImpl::DecodeLoop(PacketList* packet_list, Operations* operation, ", pt=" << static_cast(packet->header.payloadType) << ", ssrc=" << packet->header.ssrc << ", len=" << packet->payload_length; - memset(&decoded_buffer_[*decoded_length], 0, decoder_frame_length_ * - decoder->channels() * sizeof(decoded_buffer_[0])); + memset(&decoded_buffer_[*decoded_length], 0, + decoder_frame_length_ * decoder->Channels() * + sizeof(decoded_buffer_[0])); decode_length = decoder_frame_length_; } else if (!packet->primary) { // This is a redundant payload; call the special decoder method. @@ -1288,11 +1289,11 @@ int NetEqImpl::DecodeLoop(PacketList* packet_list, Operations* operation, if (decode_length > 0) { *decoded_length += decode_length; // Update |decoder_frame_length_| with number of samples per channel. - decoder_frame_length_ = decode_length / - static_cast(decoder->channels()); - LOG(LS_VERBOSE) << "Decoded " << decode_length << " samples (" << - decoder->channels() << " channel(s) -> " << decoder_frame_length_ << - " samples per channel)"; + decoder_frame_length_ = + decode_length / static_cast(decoder->Channels()); + LOG(LS_VERBOSE) << "Decoded " << decode_length << " samples (" + << decoder->Channels() << " channel(s) -> " + << decoder_frame_length_ << " samples per channel)"; } else if (decode_length < 0) { // Error. LOG_FERR2(LS_WARNING, Decode, decode_length, payload_length); diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc index 0a5c6a416..3823d9675 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc @@ -270,6 +270,7 @@ TEST_F(NetEqImplTest, InsertPacket) { // Create a mock decoder object. MockAudioDecoder mock_decoder; + EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1)); // BWE update function called with first packet. EXPECT_CALL(mock_decoder, IncomingPacket(_, kPayloadLength, @@ -447,6 +448,8 @@ TEST_F(NetEqImplTest, VerifyTimestampPropagation) { return 0; } + size_t Channels() const override { return 1; } + uint16_t next_value() const { return next_value_; } private: @@ -519,6 +522,7 @@ TEST_F(NetEqImplTest, ReorderedPacket) { // Create a mock decoder object. MockAudioDecoder mock_decoder; EXPECT_CALL(mock_decoder, Init()).WillRepeatedly(Return(0)); + EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1)); EXPECT_CALL(mock_decoder, IncomingPacket(_, kPayloadLengthBytes, _, _, _)) .WillRepeatedly(Return(0)); int16_t dummy_output[kPayloadLengthSamples] = {0}; @@ -682,6 +686,7 @@ TEST_F(NetEqImplTest, CodecInternalCng) { // Create a mock decoder object. MockAudioDecoder mock_decoder; EXPECT_CALL(mock_decoder, Init()).WillRepeatedly(Return(0)); + EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1)); EXPECT_CALL(mock_decoder, IncomingPacket(_, kPayloadLengthBytes, _, _, _)) .WillRepeatedly(Return(0)); @@ -824,6 +829,7 @@ TEST_F(NetEqImplTest, UnsupportedDecoder) { MOCK_CONST_METHOD2(PacketDuration, int(const uint8_t*, size_t)); MOCK_METHOD5(DecodeInternal, int(const uint8_t*, size_t, int, int16_t*, SpeechType*)); + size_t Channels() const override { return 1; } } decoder_; const uint8_t kFirstPayloadValue = 1; diff --git a/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc index a49f95781..e1a0f69df 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc @@ -61,8 +61,8 @@ class MockAudioDecoderOpus : public AudioDecoderOpus { int16_t* decoded, SpeechType* speech_type) override { *speech_type = kSpeech; - memset(decoded, 0, sizeof(int16_t) * kPacketDuration * channels_); - return kPacketDuration * channels_; + memset(decoded, 0, sizeof(int16_t) * kPacketDuration * Channels()); + return kPacketDuration * Channels(); } int DecodeRedundantInternal(const uint8_t* encoded, diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc b/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc index 17391daeb..3eb4a2980 100644 --- a/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc +++ b/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc @@ -21,7 +21,7 @@ NetEqExternalDecoderTest::NetEqExternalDecoderTest(NetEqDecoder codec, : codec_(codec), decoder_(decoder), sample_rate_hz_(CodecSampleRateHz(codec_)), - channels_(static_cast(decoder_->channels())) { + channels_(static_cast(decoder_->Channels())) { NetEq::Config config; config.sample_rate_hz = sample_rate_hz_; neteq_.reset(NetEq::Create(config));