diff --git a/webrtc/api/audio_codecs/g722/BUILD.gn b/webrtc/api/audio_codecs/g722/BUILD.gn new file mode 100644 index 0000000000..78708f5194 --- /dev/null +++ b/webrtc/api/audio_codecs/g722/BUILD.gn @@ -0,0 +1,26 @@ +# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. +# +# Use of this source code is governed by a BSD-style license +# that can be found in the LICENSE file in the root of the source +# tree. An additional intellectual property rights grant can be found +# in the file PATENTS. All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. + +import("../../../webrtc.gni") +if (is_android) { + import("//build/config/android/config.gni") + import("//build/config/android/rules.gni") +} + +rtc_static_library("audio_decoder_g722") { + sources = [ + "audio_decoder_g722.cc", + "audio_decoder_g722.h", + ] + deps = [ + "..:audio_codecs_api", + "../../..:webrtc_common", + "../../../base:rtc_base_approved", + "../../../modules/audio_coding:g722", + ] +} diff --git a/webrtc/api/audio_codecs/g722/audio_decoder_g722.cc b/webrtc/api/audio_codecs/g722/audio_decoder_g722.cc new file mode 100644 index 0000000000..e4cb1b7d69 --- /dev/null +++ b/webrtc/api/audio_codecs/g722/audio_decoder_g722.cc @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/api/audio_codecs/g722/audio_decoder_g722.h" + +#include +#include + +#include "webrtc/base/ptr_util.h" +#include "webrtc/base/safe_conversions.h" +#include "webrtc/common_types.h" +#include "webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h" + +namespace webrtc { + +rtc::Optional AudioDecoderG722::SdpToConfig( + const SdpAudioFormat& format) { + return STR_CASE_CMP(format.name.c_str(), "g722") == 0 && + format.clockrate_hz == 8000 + ? rtc::Optional(Config()) + : rtc::Optional(); +} + +void AudioDecoderG722::AppendSupportedDecoders( + std::vector* specs) { + specs->push_back({{"g722", 8000, 1}, {16000, 1, 64000}}); +} + +std::unique_ptr AudioDecoderG722::MakeAudioDecoder( + Config config) { + return rtc::MakeUnique(); +} + +} // namespace webrtc diff --git a/webrtc/api/audio_codecs/g722/audio_decoder_g722.h b/webrtc/api/audio_codecs/g722/audio_decoder_g722.h new file mode 100644 index 0000000000..32a46d7348 --- /dev/null +++ b/webrtc/api/audio_codecs/g722/audio_decoder_g722.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_API_AUDIO_CODECS_G722_AUDIO_DECODER_G722_H_ +#define WEBRTC_API_AUDIO_CODECS_G722_AUDIO_DECODER_G722_H_ + +#include +#include + +#include "webrtc/api/audio_codecs/audio_decoder.h" +#include "webrtc/api/audio_codecs/audio_format.h" +#include "webrtc/base/optional.h" + +namespace webrtc { + +// G722 decoder API for use as a template parameter to +// CreateAudioDecoderFactory<...>(). +// +// NOTE: This struct is still under development and may change without notice. +struct AudioDecoderG722 { + struct Config {}; // Empty---no config values needed! + static rtc::Optional SdpToConfig(const SdpAudioFormat& audio_format); + static void AppendSupportedDecoders(std::vector* specs); + static std::unique_ptr MakeAudioDecoder(Config config); +}; + +} // namespace webrtc + +#endif // WEBRTC_API_AUDIO_CODECS_G722_AUDIO_DECODER_G722_H_ diff --git a/webrtc/api/audio_codecs/test/BUILD.gn b/webrtc/api/audio_codecs/test/BUILD.gn index 22b3f4e8e9..914acf46a4 100644 --- a/webrtc/api/audio_codecs/test/BUILD.gn +++ b/webrtc/api/audio_codecs/test/BUILD.gn @@ -24,6 +24,7 @@ if (rtc_include_tests) { "../../../base:rtc_base_approved", "../../../test:audio_codec_mocks", "../../../test:test_support", + "../g722:audio_decoder_g722", "//testing/gmock", ] } diff --git a/webrtc/api/audio_codecs/test/audio_decoder_factory_template_unittest.cc b/webrtc/api/audio_codecs/test/audio_decoder_factory_template_unittest.cc index 170bba79bf..21fbc7c616 100644 --- a/webrtc/api/audio_codecs/test/audio_decoder_factory_template_unittest.cc +++ b/webrtc/api/audio_codecs/test/audio_decoder_factory_template_unittest.cc @@ -9,6 +9,7 @@ */ #include "webrtc/api/audio_codecs/audio_decoder_factory_template.h" +#include "webrtc/api/audio_codecs/g722/audio_decoder_g722.h" #include "webrtc/base/ptr_util.h" #include "webrtc/test/gmock.h" #include "webrtc/test/gtest.h" @@ -110,4 +111,17 @@ TEST(AudioDecoderFactoryTemplateTest, TwoDecoderTypes) { EXPECT_EQ(16000, dec2->SampleRateHz()); } +TEST(AudioDecoderFactoryTemplateTest, G722) { + auto factory = CreateAudioDecoderFactory(); + EXPECT_THAT(factory->GetSupportedDecoders(), + testing::ElementsAre( + AudioCodecSpec{{"g722", 8000, 1}, {16000, 1, 64000}})); + EXPECT_FALSE(factory->IsSupportedDecoder({"foo", 8000, 1})); + EXPECT_TRUE(factory->IsSupportedDecoder({"g722", 8000, 1})); + EXPECT_EQ(nullptr, factory->MakeAudioDecoder({"bar", 16000, 1})); + auto dec = factory->MakeAudioDecoder({"g722", 8000, 1}); + ASSERT_NE(nullptr, dec); + EXPECT_EQ(16000, dec->SampleRateHz()); +} + } // namespace webrtc diff --git a/webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory_internal.cc b/webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory_internal.cc index cd7bf3babe..cbf735ee2e 100644 --- a/webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory_internal.cc +++ b/webrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory_internal.cc @@ -130,7 +130,7 @@ NamedDecoderConstructor decoder_constructors[] = { if (format.clockrate_hz == 8000) { if (format.num_channels == 1) { if (out) { - out->reset(new AudioDecoderG722); + out->reset(new AudioDecoderG722Impl); } return true; } else if (format.num_channels == 2) { diff --git a/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.cc b/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.cc index 3a0f6ede66..d38888f53e 100644 --- a/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.cc +++ b/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.cc @@ -18,24 +18,24 @@ namespace webrtc { -AudioDecoderG722::AudioDecoderG722() { +AudioDecoderG722Impl::AudioDecoderG722Impl() { WebRtcG722_CreateDecoder(&dec_state_); WebRtcG722_DecoderInit(dec_state_); } -AudioDecoderG722::~AudioDecoderG722() { +AudioDecoderG722Impl::~AudioDecoderG722Impl() { WebRtcG722_FreeDecoder(dec_state_); } -bool AudioDecoderG722::HasDecodePlc() const { +bool AudioDecoderG722Impl::HasDecodePlc() const { return false; } -int AudioDecoderG722::DecodeInternal(const uint8_t* encoded, - size_t encoded_len, - int sample_rate_hz, - int16_t* decoded, - SpeechType* speech_type) { +int AudioDecoderG722Impl::DecodeInternal(const uint8_t* encoded, + size_t encoded_len, + int sample_rate_hz, + int16_t* decoded, + SpeechType* speech_type) { RTC_DCHECK_EQ(SampleRateHz(), sample_rate_hz); int16_t temp_type = 1; // Default is speech. size_t ret = @@ -44,28 +44,28 @@ int AudioDecoderG722::DecodeInternal(const uint8_t* encoded, return static_cast(ret); } -void AudioDecoderG722::Reset() { +void AudioDecoderG722Impl::Reset() { WebRtcG722_DecoderInit(dec_state_); } -std::vector AudioDecoderG722::ParsePayload( +std::vector AudioDecoderG722Impl::ParsePayload( rtc::Buffer&& payload, uint32_t timestamp) { return LegacyEncodedAudioFrame::SplitBySamples(this, std::move(payload), timestamp, 8, 16); } -int AudioDecoderG722::PacketDuration(const uint8_t* encoded, - size_t encoded_len) const { +int AudioDecoderG722Impl::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()); } -int AudioDecoderG722::SampleRateHz() const { +int AudioDecoderG722Impl::SampleRateHz() const { return 16000; } -size_t AudioDecoderG722::Channels() const { +size_t AudioDecoderG722Impl::Channels() const { return 1; } diff --git a/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h b/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h index c53c78c67e..ab104f2e20 100644 --- a/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h +++ b/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h @@ -18,10 +18,10 @@ typedef struct WebRtcG722DecInst G722DecInst; namespace webrtc { -class AudioDecoderG722 final : public AudioDecoder { +class AudioDecoderG722Impl final : public AudioDecoder { public: - AudioDecoderG722(); - ~AudioDecoderG722() override; + AudioDecoderG722Impl(); + ~AudioDecoderG722Impl() override; bool HasDecodePlc() const override; void Reset() override; std::vector ParsePayload(rtc::Buffer&& payload, @@ -39,7 +39,7 @@ class AudioDecoderG722 final : public AudioDecoder { private: G722DecInst* dec_state_; - RTC_DISALLOW_COPY_AND_ASSIGN(AudioDecoderG722); + RTC_DISALLOW_COPY_AND_ASSIGN(AudioDecoderG722Impl); }; class AudioDecoderG722Stereo final : public AudioDecoder { diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc index 4a4e62b4e3..b1a07edf14 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc @@ -402,7 +402,7 @@ class AudioDecoderG722Test : public AudioDecoderTest { codec_input_rate_hz_ = 16000; frame_size_ = 160; data_length_ = 10 * frame_size_; - decoder_ = new AudioDecoderG722; + decoder_ = new AudioDecoderG722Impl; assert(decoder_); AudioEncoderG722::Config config; config.frame_size_ms = 10;