G722 implementation of the AudioDecoderFactoryTemplate API

Now the templated AudioDecoderFactory can create G722 decoders!

BUG=webrtc:7839

Review-Url: https://codereview.webrtc.org/2940833002
Cr-Commit-Position: refs/heads/master@{#18643}
This commit is contained in:
kwiberg 2017-06-17 17:30:09 -07:00 committed by Commit Bot
parent 0eacd88568
commit b1ed7f09c0
9 changed files with 138 additions and 20 deletions

View File

@ -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",
]
}

View File

@ -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 <memory>
#include <vector>
#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::Config> AudioDecoderG722::SdpToConfig(
const SdpAudioFormat& format) {
return STR_CASE_CMP(format.name.c_str(), "g722") == 0 &&
format.clockrate_hz == 8000
? rtc::Optional<Config>(Config())
: rtc::Optional<Config>();
}
void AudioDecoderG722::AppendSupportedDecoders(
std::vector<AudioCodecSpec>* specs) {
specs->push_back({{"g722", 8000, 1}, {16000, 1, 64000}});
}
std::unique_ptr<AudioDecoder> AudioDecoderG722::MakeAudioDecoder(
Config config) {
return rtc::MakeUnique<AudioDecoderG722Impl>();
}
} // namespace webrtc

View File

@ -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 <memory>
#include <vector>
#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<Config> SdpToConfig(const SdpAudioFormat& audio_format);
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(Config config);
};
} // namespace webrtc
#endif // WEBRTC_API_AUDIO_CODECS_G722_AUDIO_DECODER_G722_H_

View File

@ -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",
]
}

View File

@ -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<AudioDecoderG722>();
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

View File

@ -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) {

View File

@ -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<int>(ret);
}
void AudioDecoderG722::Reset() {
void AudioDecoderG722Impl::Reset() {
WebRtcG722_DecoderInit(dec_state_);
}
std::vector<AudioDecoder::ParseResult> AudioDecoderG722::ParsePayload(
std::vector<AudioDecoder::ParseResult> 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<int>(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;
}

View File

@ -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<ParseResult> 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 {

View File

@ -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;