Expose ILBC codec in webrtc/api/audio_codecs/
BUG=webrtc:7834, webrtc:7840 Review-Url: https://codereview.webrtc.org/2951873002 Cr-Commit-Position: refs/heads/master@{#18803}
This commit is contained in:
45
webrtc/api/audio_codecs/ilbc/BUILD.gn
Normal file
45
webrtc/api/audio_codecs/ilbc/BUILD.gn
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# 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_source_set("audio_encoder_ilbc_config") {
|
||||||
|
sources = [
|
||||||
|
"audio_encoder_ilbc_config.h",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc_static_library("audio_encoder_ilbc") {
|
||||||
|
sources = [
|
||||||
|
"audio_encoder_ilbc.cc",
|
||||||
|
"audio_encoder_ilbc.h",
|
||||||
|
]
|
||||||
|
deps = [
|
||||||
|
":audio_encoder_ilbc_config",
|
||||||
|
"..:audio_codecs_api",
|
||||||
|
"../../../base:rtc_base_approved",
|
||||||
|
"../../../modules/audio_coding:ilbc",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc_static_library("audio_decoder_ilbc") {
|
||||||
|
sources = [
|
||||||
|
"audio_decoder_ilbc.cc",
|
||||||
|
"audio_decoder_ilbc.h",
|
||||||
|
]
|
||||||
|
deps = [
|
||||||
|
"..:audio_codecs_api",
|
||||||
|
"../../..:webrtc_common",
|
||||||
|
"../../../base:rtc_base_approved",
|
||||||
|
"../../../modules/audio_coding:ilbc",
|
||||||
|
]
|
||||||
|
}
|
||||||
40
webrtc/api/audio_codecs/ilbc/audio_decoder_ilbc.cc
Normal file
40
webrtc/api/audio_codecs/ilbc/audio_decoder_ilbc.cc
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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/ilbc/audio_decoder_ilbc.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "webrtc/base/ptr_util.h"
|
||||||
|
#include "webrtc/common_types.h"
|
||||||
|
#include "webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
rtc::Optional<AudioDecoderIlbc::Config> AudioDecoderIlbc::SdpToConfig(
|
||||||
|
const SdpAudioFormat& format) {
|
||||||
|
return STR_CASE_CMP(format.name.c_str(), "ilbc") == 0 &&
|
||||||
|
format.clockrate_hz == 8000 && format.num_channels == 1
|
||||||
|
? rtc::Optional<Config>(Config())
|
||||||
|
: rtc::Optional<Config>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDecoderIlbc::AppendSupportedDecoders(
|
||||||
|
std::vector<AudioCodecSpec>* specs) {
|
||||||
|
specs->push_back({{"ILBC", 8000, 1}, {8000, 1, 13300}});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioDecoder> AudioDecoderIlbc::MakeAudioDecoder(
|
||||||
|
Config config) {
|
||||||
|
return rtc::MakeUnique<AudioDecoderIlbcImpl>();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
36
webrtc/api/audio_codecs/ilbc/audio_decoder_ilbc.h
Normal file
36
webrtc/api/audio_codecs/ilbc/audio_decoder_ilbc.h
Normal 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_ILBC_AUDIO_DECODER_ILBC_H_
|
||||||
|
#define WEBRTC_API_AUDIO_CODECS_ILBC_AUDIO_DECODER_ILBC_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 {
|
||||||
|
|
||||||
|
// ILBC decoder API for use as a template parameter to
|
||||||
|
// CreateAudioDecoderFactory<...>().
|
||||||
|
//
|
||||||
|
// NOTE: This struct is still under development and may change without notice.
|
||||||
|
struct AudioDecoderIlbc {
|
||||||
|
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_ILBC_AUDIO_DECODER_ILBC_H_
|
||||||
63
webrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.cc
Normal file
63
webrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.cc
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* 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/ilbc/audio_encoder_ilbc.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "webrtc/base/ptr_util.h"
|
||||||
|
#include "webrtc/base/safe_conversions.h"
|
||||||
|
#include "webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
namespace {
|
||||||
|
int GetIlbcBitrate(int ptime) {
|
||||||
|
switch (ptime) {
|
||||||
|
case 20:
|
||||||
|
case 40:
|
||||||
|
// 38 bytes per frame of 20 ms => 15200 bits/s.
|
||||||
|
return 15200;
|
||||||
|
case 30:
|
||||||
|
case 60:
|
||||||
|
// 50 bytes per frame of 30 ms => (approx) 13333 bits/s.
|
||||||
|
return 13333;
|
||||||
|
default:
|
||||||
|
FATAL();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
rtc::Optional<AudioEncoderIlbcConfig> AudioEncoderIlbc::SdpToConfig(
|
||||||
|
const SdpAudioFormat& format) {
|
||||||
|
return AudioEncoderIlbcImpl::SdpToConfig(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioEncoderIlbc::AppendSupportedEncoders(
|
||||||
|
std::vector<AudioCodecSpec>* specs) {
|
||||||
|
const SdpAudioFormat fmt = {"ILBC", 8000, 1};
|
||||||
|
const AudioCodecInfo info = QueryAudioEncoder(*SdpToConfig(fmt));
|
||||||
|
specs->push_back({fmt, info});
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioCodecInfo AudioEncoderIlbc::QueryAudioEncoder(
|
||||||
|
const AudioEncoderIlbcConfig& config) {
|
||||||
|
RTC_DCHECK(config.IsOk());
|
||||||
|
return {8000, 1, GetIlbcBitrate(config.frame_size_ms)};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioEncoder> AudioEncoderIlbc::MakeAudioEncoder(
|
||||||
|
const AudioEncoderIlbcConfig& config,
|
||||||
|
int payload_type) {
|
||||||
|
RTC_DCHECK(config.IsOk());
|
||||||
|
return rtc::MakeUnique<AudioEncoderIlbcImpl>(config, payload_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
40
webrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.h
Normal file
40
webrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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_ILBC_AUDIO_ENCODER_ILBC_H_
|
||||||
|
#define WEBRTC_API_AUDIO_CODECS_ILBC_AUDIO_ENCODER_ILBC_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "webrtc/api/audio_codecs/audio_encoder.h"
|
||||||
|
#include "webrtc/api/audio_codecs/audio_format.h"
|
||||||
|
#include "webrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_config.h"
|
||||||
|
#include "webrtc/base/optional.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
// ILBC encoder API for use as a template parameter to
|
||||||
|
// CreateAudioEncoderFactory<...>().
|
||||||
|
//
|
||||||
|
// NOTE: This struct is still under development and may change without notice.
|
||||||
|
struct AudioEncoderIlbc {
|
||||||
|
static rtc::Optional<AudioEncoderIlbcConfig> SdpToConfig(
|
||||||
|
const SdpAudioFormat& audio_format);
|
||||||
|
static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
|
||||||
|
static AudioCodecInfo QueryAudioEncoder(const AudioEncoderIlbcConfig& config);
|
||||||
|
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
|
||||||
|
const AudioEncoderIlbcConfig& config,
|
||||||
|
int payload_type);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // WEBRTC_API_AUDIO_CODECS_ILBC_AUDIO_ENCODER_ILBC_H_
|
||||||
29
webrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_config.h
Normal file
29
webrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_config.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* 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_ILBC_AUDIO_ENCODER_ILBC_CONFIG_H_
|
||||||
|
#define WEBRTC_API_AUDIO_CODECS_ILBC_AUDIO_ENCODER_ILBC_CONFIG_H_
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
// NOTE: This struct is still under development and may change without notice.
|
||||||
|
struct AudioEncoderIlbcConfig {
|
||||||
|
bool IsOk() const {
|
||||||
|
return (frame_size_ms == 20 || frame_size_ms == 30 || frame_size_ms == 40 ||
|
||||||
|
frame_size_ms == 60);
|
||||||
|
}
|
||||||
|
int frame_size_ms = 30; // Valid values are 20, 30, 40, and 60 ms.
|
||||||
|
// Note that frame size 40 ms produces encodings with two 20 ms frames in
|
||||||
|
// them, and frame size 60 ms consists of two 30 ms frames.
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // WEBRTC_API_AUDIO_CODECS_ILBC_AUDIO_ENCODER_ILBC_CONFIG_H_
|
||||||
@ -26,6 +26,8 @@ if (rtc_include_tests) {
|
|||||||
"../../../test:test_support",
|
"../../../test:test_support",
|
||||||
"../g722:audio_decoder_g722",
|
"../g722:audio_decoder_g722",
|
||||||
"../g722:audio_encoder_g722",
|
"../g722:audio_encoder_g722",
|
||||||
|
"../ilbc:audio_decoder_ilbc",
|
||||||
|
"../ilbc:audio_encoder_ilbc",
|
||||||
"//testing/gmock",
|
"//testing/gmock",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "webrtc/api/audio_codecs/audio_decoder_factory_template.h"
|
#include "webrtc/api/audio_codecs/audio_decoder_factory_template.h"
|
||||||
#include "webrtc/api/audio_codecs/g722/audio_decoder_g722.h"
|
#include "webrtc/api/audio_codecs/g722/audio_decoder_g722.h"
|
||||||
|
#include "webrtc/api/audio_codecs/ilbc/audio_decoder_ilbc.h"
|
||||||
#include "webrtc/base/ptr_util.h"
|
#include "webrtc/base/ptr_util.h"
|
||||||
#include "webrtc/test/gmock.h"
|
#include "webrtc/test/gmock.h"
|
||||||
#include "webrtc/test/gtest.h"
|
#include "webrtc/test/gtest.h"
|
||||||
@ -131,4 +132,17 @@ TEST(AudioDecoderFactoryTemplateTest, G722) {
|
|||||||
ASSERT_EQ(nullptr, dec3);
|
ASSERT_EQ(nullptr, dec3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(AudioDecoderFactoryTemplateTest, Ilbc) {
|
||||||
|
auto factory = CreateAudioDecoderFactory<AudioDecoderIlbc>();
|
||||||
|
EXPECT_THAT(factory->GetSupportedDecoders(),
|
||||||
|
testing::ElementsAre(
|
||||||
|
AudioCodecSpec{{"ILBC", 8000, 1}, {8000, 1, 13300}}));
|
||||||
|
EXPECT_FALSE(factory->IsSupportedDecoder({"foo", 8000, 1}));
|
||||||
|
EXPECT_TRUE(factory->IsSupportedDecoder({"ilbc", 8000, 1}));
|
||||||
|
EXPECT_EQ(nullptr, factory->MakeAudioDecoder({"bar", 8000, 1}));
|
||||||
|
auto dec = factory->MakeAudioDecoder({"ilbc", 8000, 1});
|
||||||
|
ASSERT_NE(nullptr, dec);
|
||||||
|
EXPECT_EQ(8000, dec->SampleRateHz());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "webrtc/api/audio_codecs/audio_encoder_factory_template.h"
|
#include "webrtc/api/audio_codecs/audio_encoder_factory_template.h"
|
||||||
#include "webrtc/api/audio_codecs/g722/audio_encoder_g722.h"
|
#include "webrtc/api/audio_codecs/g722/audio_encoder_g722.h"
|
||||||
|
#include "webrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.h"
|
||||||
#include "webrtc/base/ptr_util.h"
|
#include "webrtc/base/ptr_util.h"
|
||||||
#include "webrtc/test/gmock.h"
|
#include "webrtc/test/gmock.h"
|
||||||
#include "webrtc/test/gtest.h"
|
#include "webrtc/test/gtest.h"
|
||||||
@ -133,4 +134,19 @@ TEST(AudioEncoderFactoryTemplateTest, G722) {
|
|||||||
EXPECT_EQ(16000, enc->SampleRateHz());
|
EXPECT_EQ(16000, enc->SampleRateHz());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(AudioEncoderFactoryTemplateTest, Ilbc) {
|
||||||
|
auto factory = CreateAudioEncoderFactory<AudioEncoderIlbc>();
|
||||||
|
EXPECT_THAT(factory->GetSupportedEncoders(),
|
||||||
|
testing::ElementsAre(
|
||||||
|
AudioCodecSpec{{"ILBC", 8000, 1}, {8000, 1, 13333}}));
|
||||||
|
EXPECT_EQ(rtc::Optional<AudioCodecInfo>(),
|
||||||
|
factory->QueryAudioEncoder({"foo", 8000, 1}));
|
||||||
|
EXPECT_EQ(rtc::Optional<AudioCodecInfo>({8000, 1, 13333}),
|
||||||
|
factory->QueryAudioEncoder({"ilbc", 8000, 1}));
|
||||||
|
EXPECT_EQ(nullptr, factory->MakeAudioEncoder(17, {"bar", 8000, 1}));
|
||||||
|
auto enc = factory->MakeAudioEncoder(17, {"ilbc", 8000, 1});
|
||||||
|
ASSERT_NE(nullptr, enc);
|
||||||
|
EXPECT_EQ(8000, enc->SampleRateHz());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -322,6 +322,7 @@ rtc_static_library("ilbc") {
|
|||||||
":legacy_encoded_audio_frame",
|
":legacy_encoded_audio_frame",
|
||||||
"../..:webrtc_common",
|
"../..:webrtc_common",
|
||||||
"../../api/audio_codecs:audio_codecs_api",
|
"../../api/audio_codecs:audio_codecs_api",
|
||||||
|
"../../api/audio_codecs/ilbc:audio_encoder_ilbc_config",
|
||||||
"../../base:rtc_base_approved",
|
"../../base:rtc_base_approved",
|
||||||
"../../common_audio",
|
"../../common_audio",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -173,7 +173,7 @@ std::unique_ptr<AudioEncoder> CreateEncoder(
|
|||||||
return std::unique_ptr<AudioEncoder>(new AudioEncoderPcm16B(speech_inst));
|
return std::unique_ptr<AudioEncoder>(new AudioEncoderPcm16B(speech_inst));
|
||||||
#ifdef WEBRTC_CODEC_ILBC
|
#ifdef WEBRTC_CODEC_ILBC
|
||||||
if (STR_CASE_CMP(speech_inst.plname, "ilbc") == 0)
|
if (STR_CASE_CMP(speech_inst.plname, "ilbc") == 0)
|
||||||
return std::unique_ptr<AudioEncoder>(new AudioEncoderIlbc(speech_inst));
|
return std::unique_ptr<AudioEncoder>(new AudioEncoderIlbcImpl(speech_inst));
|
||||||
#endif
|
#endif
|
||||||
#ifdef WEBRTC_CODEC_G722
|
#ifdef WEBRTC_CODEC_G722
|
||||||
if (STR_CASE_CMP(speech_inst.plname, "g722") == 0)
|
if (STR_CASE_CMP(speech_inst.plname, "g722") == 0)
|
||||||
|
|||||||
@ -78,7 +78,7 @@ NamedDecoderConstructor decoder_constructors[] = {
|
|||||||
[](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) {
|
[](const SdpAudioFormat& format, std::unique_ptr<AudioDecoder>* out) {
|
||||||
if (format.clockrate_hz == 8000 && format.num_channels == 1) {
|
if (format.clockrate_hz == 8000 && format.num_channels == 1) {
|
||||||
if (out) {
|
if (out) {
|
||||||
out->reset(new AudioDecoderIlbc);
|
out->reset(new AudioDecoderIlbcImpl);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -65,7 +65,7 @@ NamedEncoderFactory encoder_factories[] = {
|
|||||||
NamedEncoderFactory::ForEncoder<AudioEncoderG722Impl>(),
|
NamedEncoderFactory::ForEncoder<AudioEncoderG722Impl>(),
|
||||||
#endif
|
#endif
|
||||||
#ifdef WEBRTC_CODEC_ILBC
|
#ifdef WEBRTC_CODEC_ILBC
|
||||||
NamedEncoderFactory::ForEncoder<AudioEncoderIlbc>(),
|
NamedEncoderFactory::ForEncoder<AudioEncoderIlbcImpl>(),
|
||||||
#endif
|
#endif
|
||||||
#if defined(WEBRTC_CODEC_ISACFX)
|
#if defined(WEBRTC_CODEC_ISACFX)
|
||||||
NamedEncoderFactory::ForEncoder<AudioEncoderIsacFix>(),
|
NamedEncoderFactory::ForEncoder<AudioEncoderIsacFix>(),
|
||||||
|
|||||||
@ -19,20 +19,20 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
AudioDecoderIlbc::AudioDecoderIlbc() {
|
AudioDecoderIlbcImpl::AudioDecoderIlbcImpl() {
|
||||||
WebRtcIlbcfix_DecoderCreate(&dec_state_);
|
WebRtcIlbcfix_DecoderCreate(&dec_state_);
|
||||||
WebRtcIlbcfix_Decoderinit30Ms(dec_state_);
|
WebRtcIlbcfix_Decoderinit30Ms(dec_state_);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioDecoderIlbc::~AudioDecoderIlbc() {
|
AudioDecoderIlbcImpl::~AudioDecoderIlbcImpl() {
|
||||||
WebRtcIlbcfix_DecoderFree(dec_state_);
|
WebRtcIlbcfix_DecoderFree(dec_state_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioDecoderIlbc::HasDecodePlc() const {
|
bool AudioDecoderIlbcImpl::HasDecodePlc() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioDecoderIlbc::DecodeInternal(const uint8_t* encoded,
|
int AudioDecoderIlbcImpl::DecodeInternal(const uint8_t* encoded,
|
||||||
size_t encoded_len,
|
size_t encoded_len,
|
||||||
int sample_rate_hz,
|
int sample_rate_hz,
|
||||||
int16_t* decoded,
|
int16_t* decoded,
|
||||||
@ -45,22 +45,22 @@ int AudioDecoderIlbc::DecodeInternal(const uint8_t* encoded,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t AudioDecoderIlbc::DecodePlc(size_t num_frames, int16_t* decoded) {
|
size_t AudioDecoderIlbcImpl::DecodePlc(size_t num_frames, int16_t* decoded) {
|
||||||
return WebRtcIlbcfix_NetEqPlc(dec_state_, decoded, num_frames);
|
return WebRtcIlbcfix_NetEqPlc(dec_state_, decoded, num_frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDecoderIlbc::Reset() {
|
void AudioDecoderIlbcImpl::Reset() {
|
||||||
WebRtcIlbcfix_Decoderinit30Ms(dec_state_);
|
WebRtcIlbcfix_Decoderinit30Ms(dec_state_);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<AudioDecoder::ParseResult> AudioDecoderIlbc::ParsePayload(
|
std::vector<AudioDecoder::ParseResult> AudioDecoderIlbcImpl::ParsePayload(
|
||||||
rtc::Buffer&& payload,
|
rtc::Buffer&& payload,
|
||||||
uint32_t timestamp) {
|
uint32_t timestamp) {
|
||||||
std::vector<ParseResult> results;
|
std::vector<ParseResult> results;
|
||||||
size_t bytes_per_frame;
|
size_t bytes_per_frame;
|
||||||
int timestamps_per_frame;
|
int timestamps_per_frame;
|
||||||
if (payload.size() >= 950) {
|
if (payload.size() >= 950) {
|
||||||
LOG(LS_WARNING) << "AudioDecoderIlbc::ParsePayload: Payload too large";
|
LOG(LS_WARNING) << "AudioDecoderIlbcImpl::ParsePayload: Payload too large";
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
if (payload.size() % 38 == 0) {
|
if (payload.size() % 38 == 0) {
|
||||||
@ -72,7 +72,7 @@ std::vector<AudioDecoder::ParseResult> AudioDecoderIlbc::ParsePayload(
|
|||||||
bytes_per_frame = 50;
|
bytes_per_frame = 50;
|
||||||
timestamps_per_frame = 240;
|
timestamps_per_frame = 240;
|
||||||
} else {
|
} else {
|
||||||
LOG(LS_WARNING) << "AudioDecoderIlbc::ParsePayload: Invalid payload";
|
LOG(LS_WARNING) << "AudioDecoderIlbcImpl::ParsePayload: Invalid payload";
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,11 +97,11 @@ std::vector<AudioDecoder::ParseResult> AudioDecoderIlbc::ParsePayload(
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioDecoderIlbc::SampleRateHz() const {
|
int AudioDecoderIlbcImpl::SampleRateHz() const {
|
||||||
return 8000;
|
return 8000;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t AudioDecoderIlbc::Channels() const {
|
size_t AudioDecoderIlbcImpl::Channels() const {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,10 +18,10 @@ typedef struct iLBC_decinst_t_ IlbcDecoderInstance;
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
class AudioDecoderIlbc final : public AudioDecoder {
|
class AudioDecoderIlbcImpl final : public AudioDecoder {
|
||||||
public:
|
public:
|
||||||
AudioDecoderIlbc();
|
AudioDecoderIlbcImpl();
|
||||||
~AudioDecoderIlbc() override;
|
~AudioDecoderIlbcImpl() override;
|
||||||
bool HasDecodePlc() const override;
|
bool HasDecodePlc() const override;
|
||||||
size_t DecodePlc(size_t num_frames, int16_t* decoded) override;
|
size_t DecodePlc(size_t num_frames, int16_t* decoded) override;
|
||||||
void Reset() override;
|
void Reset() override;
|
||||||
@ -39,7 +39,7 @@ class AudioDecoderIlbc final : public AudioDecoder {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
IlbcDecoderInstance* dec_state_;
|
IlbcDecoderInstance* dec_state_;
|
||||||
RTC_DISALLOW_COPY_AND_ASSIGN(AudioDecoderIlbc);
|
RTC_DISALLOW_COPY_AND_ASSIGN(AudioDecoderIlbcImpl);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -24,34 +24,20 @@ namespace {
|
|||||||
|
|
||||||
const int kSampleRateHz = 8000;
|
const int kSampleRateHz = 8000;
|
||||||
|
|
||||||
AudioEncoderIlbc::Config CreateConfig(const CodecInst& codec_inst) {
|
AudioEncoderIlbcConfig CreateConfig(const CodecInst& codec_inst) {
|
||||||
AudioEncoderIlbc::Config config;
|
AudioEncoderIlbcConfig config;
|
||||||
config.frame_size_ms = codec_inst.pacsize / 8;
|
config.frame_size_ms = codec_inst.pacsize / 8;
|
||||||
config.payload_type = codec_inst.pltype;
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioEncoderIlbc::Config CreateConfig(int payload_type,
|
|
||||||
const SdpAudioFormat& format) {
|
|
||||||
AudioEncoderIlbc::Config config;
|
|
||||||
config.payload_type = payload_type;
|
|
||||||
auto ptime_iter = format.parameters.find("ptime");
|
|
||||||
if (ptime_iter != format.parameters.end()) {
|
|
||||||
auto ptime = rtc::StringToNumber<int>(ptime_iter->second);
|
|
||||||
if (ptime && *ptime > 0) {
|
|
||||||
const int whole_packets = *ptime / 10;
|
|
||||||
config.frame_size_ms = std::max(20, std::min(whole_packets * 10, 60));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetIlbcBitrate(int ptime) {
|
int GetIlbcBitrate(int ptime) {
|
||||||
switch (ptime) {
|
switch (ptime) {
|
||||||
case 20: case 40:
|
case 20:
|
||||||
|
case 40:
|
||||||
// 38 bytes per frame of 20 ms => 15200 bits/s.
|
// 38 bytes per frame of 20 ms => 15200 bits/s.
|
||||||
return 15200;
|
return 15200;
|
||||||
case 30: case 60:
|
case 30:
|
||||||
|
case 60:
|
||||||
// 50 bytes per frame of 30 ms => (approx) 13333 bits/s.
|
// 50 bytes per frame of 30 ms => (approx) 13333 bits/s.
|
||||||
return 13333;
|
return 13333;
|
||||||
default:
|
default:
|
||||||
@ -61,71 +47,85 @@ int GetIlbcBitrate(int ptime) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// static
|
rtc::Optional<AudioEncoderIlbcConfig> AudioEncoderIlbcImpl::SdpToConfig(
|
||||||
const size_t AudioEncoderIlbc::kMaxSamplesPerPacket;
|
const SdpAudioFormat& format) {
|
||||||
|
if (STR_CASE_CMP(format.name.c_str(), "ilbc") != 0 ||
|
||||||
bool AudioEncoderIlbc::Config::IsOk() const {
|
format.clockrate_hz != 8000 || format.num_channels != 1) {
|
||||||
return (frame_size_ms == 20 || frame_size_ms == 30 || frame_size_ms == 40 ||
|
return rtc::Optional<AudioEncoderIlbcConfig>();
|
||||||
frame_size_ms == 60) &&
|
|
||||||
static_cast<size_t>(kSampleRateHz / 100 * (frame_size_ms / 10)) <=
|
|
||||||
kMaxSamplesPerPacket;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioEncoderIlbc::AudioEncoderIlbc(const Config& config)
|
AudioEncoderIlbcConfig config;
|
||||||
: config_(config),
|
auto ptime_iter = format.parameters.find("ptime");
|
||||||
|
if (ptime_iter != format.parameters.end()) {
|
||||||
|
auto ptime = rtc::StringToNumber<int>(ptime_iter->second);
|
||||||
|
if (ptime && *ptime > 0) {
|
||||||
|
const int whole_packets = *ptime / 10;
|
||||||
|
config.frame_size_ms = std::max(20, std::min(whole_packets * 10, 60));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return config.IsOk() ? rtc::Optional<AudioEncoderIlbcConfig>(config)
|
||||||
|
: rtc::Optional<AudioEncoderIlbcConfig>();
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioEncoderIlbcImpl::AudioEncoderIlbcImpl(const AudioEncoderIlbcConfig& config,
|
||||||
|
int payload_type)
|
||||||
|
: frame_size_ms_(config.frame_size_ms),
|
||||||
|
payload_type_(payload_type),
|
||||||
num_10ms_frames_per_packet_(
|
num_10ms_frames_per_packet_(
|
||||||
static_cast<size_t>(config.frame_size_ms / 10)),
|
static_cast<size_t>(config.frame_size_ms / 10)),
|
||||||
encoder_(nullptr) {
|
encoder_(nullptr) {
|
||||||
|
RTC_CHECK(config.IsOk());
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioEncoderIlbc::AudioEncoderIlbc(const CodecInst& codec_inst)
|
AudioEncoderIlbcImpl::AudioEncoderIlbcImpl(const CodecInst& codec_inst)
|
||||||
: AudioEncoderIlbc(CreateConfig(codec_inst)) {}
|
: AudioEncoderIlbcImpl(CreateConfig(codec_inst), codec_inst.pltype) {}
|
||||||
|
|
||||||
AudioEncoderIlbc::AudioEncoderIlbc(int payload_type,
|
AudioEncoderIlbcImpl::AudioEncoderIlbcImpl(int payload_type,
|
||||||
const SdpAudioFormat& format)
|
const SdpAudioFormat& format)
|
||||||
: AudioEncoderIlbc(CreateConfig(payload_type, format)) {}
|
: AudioEncoderIlbcImpl(*SdpToConfig(format), payload_type) {}
|
||||||
|
|
||||||
rtc::Optional<AudioCodecInfo> AudioEncoderIlbc::QueryAudioEncoder(
|
AudioEncoderIlbcImpl::~AudioEncoderIlbcImpl() {
|
||||||
const SdpAudioFormat& format) {
|
|
||||||
if (STR_CASE_CMP(format.name.c_str(), GetPayloadName()) == 0 &&
|
|
||||||
format.clockrate_hz == 8000 && format.num_channels == 1) {
|
|
||||||
Config config = CreateConfig(0, format);
|
|
||||||
if (config.IsOk()) {
|
|
||||||
return rtc::Optional<AudioCodecInfo>(
|
|
||||||
{kSampleRateHz, 1, GetIlbcBitrate(config.frame_size_ms)});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rtc::Optional<AudioCodecInfo>();
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioEncoderIlbc::~AudioEncoderIlbc() {
|
|
||||||
RTC_CHECK_EQ(0, WebRtcIlbcfix_EncoderFree(encoder_));
|
RTC_CHECK_EQ(0, WebRtcIlbcfix_EncoderFree(encoder_));
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioEncoderIlbc::SampleRateHz() const {
|
rtc::Optional<AudioCodecInfo> AudioEncoderIlbcImpl::QueryAudioEncoder(
|
||||||
|
const SdpAudioFormat& format) {
|
||||||
|
if (STR_CASE_CMP(format.name.c_str(), GetPayloadName()) == 0) {
|
||||||
|
const auto config_opt = SdpToConfig(format);
|
||||||
|
if (format.clockrate_hz == 8000 && format.num_channels == 1 &&
|
||||||
|
config_opt) {
|
||||||
|
RTC_DCHECK(config_opt->IsOk());
|
||||||
|
return rtc::Optional<AudioCodecInfo>(
|
||||||
|
{rtc::dchecked_cast<int>(kSampleRateHz), 1,
|
||||||
|
GetIlbcBitrate(config_opt->frame_size_ms)});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rtc::Optional<AudioCodecInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
int AudioEncoderIlbcImpl::SampleRateHz() const {
|
||||||
return kSampleRateHz;
|
return kSampleRateHz;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t AudioEncoderIlbc::NumChannels() const {
|
size_t AudioEncoderIlbcImpl::NumChannels() const {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t AudioEncoderIlbc::Num10MsFramesInNextPacket() const {
|
size_t AudioEncoderIlbcImpl::Num10MsFramesInNextPacket() const {
|
||||||
return num_10ms_frames_per_packet_;
|
return num_10ms_frames_per_packet_;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t AudioEncoderIlbc::Max10MsFramesInAPacket() const {
|
size_t AudioEncoderIlbcImpl::Max10MsFramesInAPacket() const {
|
||||||
return num_10ms_frames_per_packet_;
|
return num_10ms_frames_per_packet_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioEncoderIlbc::GetTargetBitrate() const {
|
int AudioEncoderIlbcImpl::GetTargetBitrate() const {
|
||||||
return GetIlbcBitrate(rtc::dchecked_cast<int>(num_10ms_frames_per_packet_) *
|
return GetIlbcBitrate(rtc::dchecked_cast<int>(num_10ms_frames_per_packet_) *
|
||||||
10);
|
10);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioEncoder::EncodedInfo AudioEncoderIlbc::EncodeImpl(
|
AudioEncoder::EncodedInfo AudioEncoderIlbcImpl::EncodeImpl(
|
||||||
uint32_t rtp_timestamp,
|
uint32_t rtp_timestamp,
|
||||||
rtc::ArrayView<const int16_t> audio,
|
rtc::ArrayView<const int16_t> audio,
|
||||||
rtc::Buffer* encoded) {
|
rtc::Buffer* encoded) {
|
||||||
@ -166,24 +166,23 @@ AudioEncoder::EncodedInfo AudioEncoderIlbc::EncodeImpl(
|
|||||||
EncodedInfo info;
|
EncodedInfo info;
|
||||||
info.encoded_bytes = encoded_bytes;
|
info.encoded_bytes = encoded_bytes;
|
||||||
info.encoded_timestamp = first_timestamp_in_buffer_;
|
info.encoded_timestamp = first_timestamp_in_buffer_;
|
||||||
info.payload_type = config_.payload_type;
|
info.payload_type = payload_type_;
|
||||||
info.encoder_type = CodecType::kIlbc;
|
info.encoder_type = CodecType::kIlbc;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioEncoderIlbc::Reset() {
|
void AudioEncoderIlbcImpl::Reset() {
|
||||||
if (encoder_)
|
if (encoder_)
|
||||||
RTC_CHECK_EQ(0, WebRtcIlbcfix_EncoderFree(encoder_));
|
RTC_CHECK_EQ(0, WebRtcIlbcfix_EncoderFree(encoder_));
|
||||||
RTC_CHECK(config_.IsOk());
|
|
||||||
RTC_CHECK_EQ(0, WebRtcIlbcfix_EncoderCreate(&encoder_));
|
RTC_CHECK_EQ(0, WebRtcIlbcfix_EncoderCreate(&encoder_));
|
||||||
const int encoder_frame_size_ms = config_.frame_size_ms > 30
|
const int encoder_frame_size_ms = frame_size_ms_ > 30
|
||||||
? config_.frame_size_ms / 2
|
? frame_size_ms_ / 2
|
||||||
: config_.frame_size_ms;
|
: frame_size_ms_;
|
||||||
RTC_CHECK_EQ(0, WebRtcIlbcfix_EncoderInit(encoder_, encoder_frame_size_ms));
|
RTC_CHECK_EQ(0, WebRtcIlbcfix_EncoderInit(encoder_, encoder_frame_size_ms));
|
||||||
num_10ms_frames_buffered_ = 0;
|
num_10ms_frames_buffered_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t AudioEncoderIlbc::RequiredOutputSizeBytes() const {
|
size_t AudioEncoderIlbcImpl::RequiredOutputSizeBytes() const {
|
||||||
switch (num_10ms_frames_per_packet_) {
|
switch (num_10ms_frames_per_packet_) {
|
||||||
case 2: return 38;
|
case 2: return 38;
|
||||||
case 3: return 50;
|
case 3: return 50;
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "webrtc/api/audio_codecs/audio_encoder.h"
|
#include "webrtc/api/audio_codecs/audio_encoder.h"
|
||||||
#include "webrtc/api/audio_codecs/audio_format.h"
|
#include "webrtc/api/audio_codecs/audio_format.h"
|
||||||
|
#include "webrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_config.h"
|
||||||
#include "webrtc/base/constructormagic.h"
|
#include "webrtc/base/constructormagic.h"
|
||||||
#include "webrtc/modules/audio_coding/codecs/ilbc/ilbc.h"
|
#include "webrtc/modules/audio_coding/codecs/ilbc/ilbc.h"
|
||||||
|
|
||||||
@ -20,21 +21,15 @@ namespace webrtc {
|
|||||||
|
|
||||||
struct CodecInst;
|
struct CodecInst;
|
||||||
|
|
||||||
class AudioEncoderIlbc final : public AudioEncoder {
|
class AudioEncoderIlbcImpl final : public AudioEncoder {
|
||||||
public:
|
public:
|
||||||
struct Config {
|
static rtc::Optional<AudioEncoderIlbcConfig> SdpToConfig(
|
||||||
bool IsOk() const;
|
const SdpAudioFormat& format);
|
||||||
|
|
||||||
int payload_type = 102;
|
AudioEncoderIlbcImpl(const AudioEncoderIlbcConfig& config, int payload_type);
|
||||||
int frame_size_ms = 30; // Valid values are 20, 30, 40, and 60 ms.
|
explicit AudioEncoderIlbcImpl(const CodecInst& codec_inst);
|
||||||
// Note that frame size 40 ms produces encodings with two 20 ms frames in
|
AudioEncoderIlbcImpl(int payload_type, const SdpAudioFormat& format);
|
||||||
// them, and frame size 60 ms consists of two 30 ms frames.
|
~AudioEncoderIlbcImpl() override;
|
||||||
};
|
|
||||||
|
|
||||||
explicit AudioEncoderIlbc(const Config& config);
|
|
||||||
explicit AudioEncoderIlbc(const CodecInst& codec_inst);
|
|
||||||
AudioEncoderIlbc(int payload_type, const SdpAudioFormat& format);
|
|
||||||
~AudioEncoderIlbc() override;
|
|
||||||
|
|
||||||
static constexpr const char* GetPayloadName() { return "ILBC"; }
|
static constexpr const char* GetPayloadName() { return "ILBC"; }
|
||||||
static rtc::Optional<AudioCodecInfo> QueryAudioEncoder(
|
static rtc::Optional<AudioCodecInfo> QueryAudioEncoder(
|
||||||
@ -53,14 +48,15 @@ class AudioEncoderIlbc final : public AudioEncoder {
|
|||||||
private:
|
private:
|
||||||
size_t RequiredOutputSizeBytes() const;
|
size_t RequiredOutputSizeBytes() const;
|
||||||
|
|
||||||
static const size_t kMaxSamplesPerPacket = 480;
|
static constexpr size_t kMaxSamplesPerPacket = 480;
|
||||||
const Config config_;
|
const int frame_size_ms_;
|
||||||
|
const int payload_type_;
|
||||||
const size_t num_10ms_frames_per_packet_;
|
const size_t num_10ms_frames_per_packet_;
|
||||||
size_t num_10ms_frames_buffered_;
|
size_t num_10ms_frames_buffered_;
|
||||||
uint32_t first_timestamp_in_buffer_;
|
uint32_t first_timestamp_in_buffer_;
|
||||||
int16_t input_buffer_[kMaxSamplesPerPacket];
|
int16_t input_buffer_[kMaxSamplesPerPacket];
|
||||||
IlbcEncoderInstance* encoder_;
|
IlbcEncoderInstance* encoder_;
|
||||||
RTC_DISALLOW_COPY_AND_ASSIGN(AudioEncoderIlbc);
|
RTC_DISALLOW_COPY_AND_ASSIGN(AudioEncoderIlbcImpl);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -17,11 +17,11 @@ namespace webrtc {
|
|||||||
|
|
||||||
TEST(IlbcTest, BadPacket) {
|
TEST(IlbcTest, BadPacket) {
|
||||||
// Get a good packet.
|
// Get a good packet.
|
||||||
AudioEncoderIlbc::Config config;
|
AudioEncoderIlbcConfig config;
|
||||||
config.frame_size_ms = 20; // We need 20 ms rather than the default 30 ms;
|
config.frame_size_ms = 20; // We need 20 ms rather than the default 30 ms;
|
||||||
// otherwise, all possible values of cb_index[2]
|
// otherwise, all possible values of cb_index[2]
|
||||||
// are valid.
|
// are valid.
|
||||||
AudioEncoderIlbc encoder(config);
|
AudioEncoderIlbcImpl encoder(config, 102);
|
||||||
std::vector<int16_t> samples(encoder.SampleRateHz() / 100, 4711);
|
std::vector<int16_t> samples(encoder.SampleRateHz() / 100, 4711);
|
||||||
rtc::Buffer packet;
|
rtc::Buffer packet;
|
||||||
int num_10ms_chunks = 0;
|
int num_10ms_chunks = 0;
|
||||||
@ -39,7 +39,7 @@ TEST(IlbcTest, BadPacket) {
|
|||||||
bad_packet[30] |= 0x80; // Bit 0.
|
bad_packet[30] |= 0x80; // Bit 0.
|
||||||
|
|
||||||
// Decode the bad packet. We expect the decoder to respond by returning -1.
|
// Decode the bad packet. We expect the decoder to respond by returning -1.
|
||||||
AudioDecoderIlbc decoder;
|
AudioDecoderIlbcImpl decoder;
|
||||||
std::vector<int16_t> decoded_samples(num_10ms_chunks * samples.size());
|
std::vector<int16_t> decoded_samples(num_10ms_chunks * samples.size());
|
||||||
AudioDecoder::SpeechType speech_type;
|
AudioDecoder::SpeechType speech_type;
|
||||||
EXPECT_EQ(-1, decoder.Decode(bad_packet.data(), bad_packet.size(),
|
EXPECT_EQ(-1, decoder.Decode(bad_packet.data(), bad_packet.size(),
|
||||||
@ -69,7 +69,7 @@ class SplitIlbcTest : public ::testing::TestWithParam<std::pair<int, int> > {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(SplitIlbcTest, NumFrames) {
|
TEST_P(SplitIlbcTest, NumFrames) {
|
||||||
AudioDecoderIlbc decoder;
|
AudioDecoderIlbcImpl decoder;
|
||||||
const size_t frame_length_samples = frame_length_ms_ * 8;
|
const size_t frame_length_samples = frame_length_ms_ * 8;
|
||||||
const auto generate_payload = [] (size_t payload_length_bytes) {
|
const auto generate_payload = [] (size_t payload_length_bytes) {
|
||||||
rtc::Buffer payload(payload_length_bytes);
|
rtc::Buffer payload(payload_length_bytes);
|
||||||
@ -120,7 +120,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
|
|
||||||
// Test too large payload size.
|
// Test too large payload size.
|
||||||
TEST(IlbcTest, SplitTooLargePayload) {
|
TEST(IlbcTest, SplitTooLargePayload) {
|
||||||
AudioDecoderIlbc decoder;
|
AudioDecoderIlbcImpl decoder;
|
||||||
constexpr size_t kPayloadLengthBytes = 950;
|
constexpr size_t kPayloadLengthBytes = 950;
|
||||||
const auto results =
|
const auto results =
|
||||||
decoder.ParsePayload(rtc::Buffer(kPayloadLengthBytes), 0);
|
decoder.ParsePayload(rtc::Buffer(kPayloadLengthBytes), 0);
|
||||||
@ -129,7 +129,7 @@ TEST(IlbcTest, SplitTooLargePayload) {
|
|||||||
|
|
||||||
// Payload not an integer number of frames.
|
// Payload not an integer number of frames.
|
||||||
TEST(IlbcTest, SplitUnevenPayload) {
|
TEST(IlbcTest, SplitUnevenPayload) {
|
||||||
AudioDecoderIlbc decoder;
|
AudioDecoderIlbcImpl decoder;
|
||||||
constexpr size_t kPayloadLengthBytes = 39; // Not an even number of frames.
|
constexpr size_t kPayloadLengthBytes = 39; // Not an even number of frames.
|
||||||
const auto results =
|
const auto results =
|
||||||
decoder.ParsePayload(rtc::Buffer(kPayloadLengthBytes), 0);
|
decoder.ParsePayload(rtc::Buffer(kPayloadLengthBytes), 0);
|
||||||
|
|||||||
@ -315,12 +315,11 @@ class AudioDecoderIlbcTest : public AudioDecoderTest {
|
|||||||
codec_input_rate_hz_ = 8000;
|
codec_input_rate_hz_ = 8000;
|
||||||
frame_size_ = 240;
|
frame_size_ = 240;
|
||||||
data_length_ = 10 * frame_size_;
|
data_length_ = 10 * frame_size_;
|
||||||
decoder_ = new AudioDecoderIlbc;
|
decoder_ = new AudioDecoderIlbcImpl;
|
||||||
assert(decoder_);
|
assert(decoder_);
|
||||||
AudioEncoderIlbc::Config config;
|
AudioEncoderIlbcConfig config;
|
||||||
config.frame_size_ms = 30;
|
config.frame_size_ms = 30;
|
||||||
config.payload_type = payload_type_;
|
audio_encoder_.reset(new AudioEncoderIlbcImpl(config, payload_type_));
|
||||||
audio_encoder_.reset(new AudioEncoderIlbc(config));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overload the default test since iLBC's function WebRtcIlbcfix_NetEqPlc does
|
// Overload the default test since iLBC's function WebRtcIlbcfix_NetEqPlc does
|
||||||
|
|||||||
@ -51,9 +51,9 @@ class NetEqIlbcQualityTest : public NetEqQualityTest {
|
|||||||
|
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
ASSERT_EQ(1u, channels_) << "iLBC supports only mono audio.";
|
ASSERT_EQ(1u, channels_) << "iLBC supports only mono audio.";
|
||||||
AudioEncoderIlbc::Config config;
|
AudioEncoderIlbcConfig config;
|
||||||
config.frame_size_ms = FLAGS_frame_size_ms;
|
config.frame_size_ms = FLAGS_frame_size_ms;
|
||||||
encoder_.reset(new AudioEncoderIlbc(config));
|
encoder_.reset(new AudioEncoderIlbcImpl(config, 102));
|
||||||
NetEqQualityTest::SetUp();
|
NetEqQualityTest::SetUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ class NetEqIlbcQualityTest : public NetEqQualityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<AudioEncoderIlbc> encoder_;
|
std::unique_ptr<AudioEncoderIlbcImpl> encoder_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(NetEqIlbcQualityTest, Test) {
|
TEST_F(NetEqIlbcQualityTest, Test) {
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
void FuzzOneInput(const uint8_t* data, size_t size) {
|
void FuzzOneInput(const uint8_t* data, size_t size) {
|
||||||
AudioDecoderIlbc dec;
|
AudioDecoderIlbcImpl dec;
|
||||||
static const int kSampleRateHz = 8000;
|
static const int kSampleRateHz = 8000;
|
||||||
static const size_t kAllocatedOuputSizeSamples = kSampleRateHz / 10;
|
static const size_t kAllocatedOuputSizeSamples = kSampleRateHz / 10;
|
||||||
int16_t output[kAllocatedOuputSizeSamples];
|
int16_t output[kAllocatedOuputSizeSamples];
|
||||||
|
|||||||
Reference in New Issue
Block a user