aboutsummaryrefslogtreecommitdiff
path: root/api/audio_codecs
diff options
context:
space:
mode:
authorAlex Loiko <aleloi@webrtc.org>2019-04-08 17:19:41 +0200
committerCommit Bot <commit-bot@chromium.org>2019-04-08 16:15:37 +0000
commite5b94160b5c01c0276d46813a97baa9d052c4847 (patch)
tree14f6471e0acd653347caa411845f127eff86e9ef /api/audio_codecs
parente9d2b4efdd5dddaa3a476c0ac2a9cf9125b39929 (diff)
downloadwebrtc-e5b94160b5c01c0276d46813a97baa9d052c4847.tar.gz
Decoder for multistream Opus.
See https://webrtc-review.googlesource.com/c/src/+/121764 for the overall vision. This CL adds a multistream Opus decoder. It's a new code-path to not interfere with the standard Opus decoder. We introduce new SDP syntax, which uses terminology of RFC 7845. We also set up the decoder side to parse it. The encoder part will come in a later CL. E.g. this is the new SDP syntax for 6.1 surround sound: "multiopus/48000/6 channel_mapping=0,4,1,2,3,5 num_streams=4 coupled_streams=2" Bug: webrtc:8649 Change-Id: Ifbc584cbb6d07aed373f223512a20d6d72cec5ec Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/129768 Commit-Queue: Alex Loiko <aleloi@webrtc.org> Reviewed-by: Oskar Sundbom <ossu@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27493}
Diffstat (limited to 'api/audio_codecs')
-rw-r--r--api/audio_codecs/BUILD.gn5
-rw-r--r--api/audio_codecs/builtin_audio_decoder_factory.cc3
-rw-r--r--api/audio_codecs/opus/BUILD.gn20
-rw-r--r--api/audio_codecs/opus/audio_decoder_multi_channel_opus.cc70
-rw-r--r--api/audio_codecs/opus/audio_decoder_multi_channel_opus.h40
-rw-r--r--api/audio_codecs/opus/audio_decoder_multi_channel_opus_config.h63
6 files changed, 199 insertions, 2 deletions
diff --git a/api/audio_codecs/BUILD.gn b/api/audio_codecs/BUILD.gn
index d07682657d..2bbeee5773 100644
--- a/api/audio_codecs/BUILD.gn
+++ b/api/audio_codecs/BUILD.gn
@@ -66,7 +66,10 @@ rtc_static_library("builtin_audio_decoder_factory") {
defines += [ "WEBRTC_USE_BUILTIN_ILBC=0" ]
}
if (rtc_include_opus) {
- deps += [ "opus:audio_decoder_opus" ]
+ deps += [
+ "opus:audio_decoder_multiopus",
+ "opus:audio_decoder_opus",
+ ]
defines += [ "WEBRTC_USE_BUILTIN_OPUS=1" ]
} else {
defines += [ "WEBRTC_USE_BUILTIN_OPUS=0" ]
diff --git a/api/audio_codecs/builtin_audio_decoder_factory.cc b/api/audio_codecs/builtin_audio_decoder_factory.cc
index e3ca1b0e06..963cfe5cb9 100644
--- a/api/audio_codecs/builtin_audio_decoder_factory.cc
+++ b/api/audio_codecs/builtin_audio_decoder_factory.cc
@@ -22,6 +22,7 @@
#endif
#include "api/audio_codecs/isac/audio_decoder_isac.h"
#if WEBRTC_USE_BUILTIN_OPUS
+#include "api/audio_codecs/opus/audio_decoder_multi_channel_opus.h"
#include "api/audio_codecs/opus/audio_decoder_opus.h" // nogncheck
#endif
@@ -53,7 +54,7 @@ rtc::scoped_refptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory() {
return CreateAudioDecoderFactory<
#if WEBRTC_USE_BUILTIN_OPUS
- AudioDecoderOpus,
+ AudioDecoderOpus, NotAdvertised<AudioDecoderMultiChannelOpus>,
#endif
AudioDecoderIsac, AudioDecoderG722,
diff --git a/api/audio_codecs/opus/BUILD.gn b/api/audio_codecs/opus/BUILD.gn
index 5552c21fa5..498e45a26e 100644
--- a/api/audio_codecs/opus/BUILD.gn
+++ b/api/audio_codecs/opus/BUILD.gn
@@ -15,6 +15,7 @@ if (is_android) {
rtc_static_library("audio_encoder_opus_config") {
visibility = [ "*" ]
sources = [
+ "audio_decoder_multi_channel_opus_config.h",
"audio_encoder_opus_config.cc",
"audio_encoder_opus_config.h",
]
@@ -68,3 +69,22 @@ rtc_static_library("audio_decoder_opus") {
"//third_party/abseil-cpp/absl/types:optional",
]
}
+
+rtc_static_library("audio_decoder_multiopus") {
+ visibility = [ "*" ]
+ poisonous = [ "audio_codecs" ]
+ sources = [
+ "audio_decoder_multi_channel_opus.cc",
+ "audio_decoder_multi_channel_opus.h",
+ ]
+ deps = [
+ ":audio_encoder_opus_config",
+ "..:audio_codecs_api",
+ "../../../modules/audio_coding:webrtc_multiopus",
+ "../../../rtc_base:rtc_base_approved",
+ "../../../rtc_base/system:rtc_export",
+ "//third_party/abseil-cpp/absl/memory",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
diff --git a/api/audio_codecs/opus/audio_decoder_multi_channel_opus.cc b/api/audio_codecs/opus/audio_decoder_multi_channel_opus.cc
new file mode 100644
index 0000000000..6ba2b6d9d3
--- /dev/null
+++ b/api/audio_codecs/opus/audio_decoder_multi_channel_opus.cc
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2019 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 "api/audio_codecs/opus/audio_decoder_multi_channel_opus.h"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/match.h"
+#include "modules/audio_coding/codecs/opus/audio_decoder_multi_channel_opus_impl.h"
+
+namespace webrtc {
+
+absl::optional<AudioDecoderMultiChannelOpusConfig>
+AudioDecoderMultiChannelOpus::SdpToConfig(const SdpAudioFormat& format) {
+ return AudioDecoderMultiChannelOpusImpl::SdpToConfig(format);
+}
+
+void AudioDecoderMultiChannelOpus::AppendSupportedDecoders(
+ std::vector<AudioCodecSpec>* specs) {
+ // To get full utilization of the surround support of the Opus lib, we can
+ // mark which channel is the low frequency effects (LFE). But that is not done
+ // ATM.
+ {
+ AudioCodecInfo surround_5_1_opus_info{48000, 6,
+ /* default_bitrate_bps= */ 128000};
+ surround_5_1_opus_info.allow_comfort_noise = false;
+ surround_5_1_opus_info.supports_network_adaption = false;
+ SdpAudioFormat opus_format({"multiopus",
+ 48000,
+ 6,
+ {{"minptime", "10"},
+ {"useinbandfec", "1"},
+ {"channel_mapping", "0,4,1,2,3,5"},
+ {"num_streams", "4"},
+ {"coupled_streams", "2"}}});
+ specs->push_back({std::move(opus_format), surround_5_1_opus_info});
+ }
+ {
+ AudioCodecInfo surround_7_1_opus_info{48000, 8,
+ /* default_bitrate_bps= */ 200000};
+ surround_7_1_opus_info.allow_comfort_noise = false;
+ surround_7_1_opus_info.supports_network_adaption = false;
+ SdpAudioFormat opus_format({"multiopus",
+ 48000,
+ 8,
+ {{"minptime", "10"},
+ {"useinbandfec", "1"},
+ {"channel_mapping", "0,6,1,2,3,4,5,7"},
+ {"num_streams", "5"},
+ {"coupled_streams", "3"}}});
+ specs->push_back({std::move(opus_format), surround_7_1_opus_info});
+ }
+}
+
+std::unique_ptr<AudioDecoder> AudioDecoderMultiChannelOpus::MakeAudioDecoder(
+ AudioDecoderMultiChannelOpusConfig config,
+ absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
+ return AudioDecoderMultiChannelOpusImpl::MakeAudioDecoder(config);
+}
+} // namespace webrtc
diff --git a/api/audio_codecs/opus/audio_decoder_multi_channel_opus.h b/api/audio_codecs/opus/audio_decoder_multi_channel_opus.h
new file mode 100644
index 0000000000..b5ca0fe41b
--- /dev/null
+++ b/api/audio_codecs/opus/audio_decoder_multi_channel_opus.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2019 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 API_AUDIO_CODECS_OPUS_AUDIO_DECODER_MULTI_CHANNEL_OPUS_H_
+#define API_AUDIO_CODECS_OPUS_AUDIO_DECODER_MULTI_CHANNEL_OPUS_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_decoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "api/audio_codecs/opus/audio_decoder_multi_channel_opus_config.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Opus decoder API for use as a template parameter to
+// CreateAudioDecoderFactory<...>().
+struct RTC_EXPORT AudioDecoderMultiChannelOpus {
+ using Config = AudioDecoderMultiChannelOpusConfig;
+ static absl::optional<AudioDecoderMultiChannelOpusConfig> SdpToConfig(
+ const SdpAudioFormat& audio_format);
+ static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
+ static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+ AudioDecoderMultiChannelOpusConfig config,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_OPUS_AUDIO_DECODER_MULTI_CHANNEL_OPUS_H_
diff --git a/api/audio_codecs/opus/audio_decoder_multi_channel_opus_config.h b/api/audio_codecs/opus/audio_decoder_multi_channel_opus_config.h
new file mode 100644
index 0000000000..30bc76e354
--- /dev/null
+++ b/api/audio_codecs/opus/audio_decoder_multi_channel_opus_config.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2019 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 API_AUDIO_CODECS_OPUS_AUDIO_DECODER_MULTI_CHANNEL_OPUS_CONFIG_H_
+#define API_AUDIO_CODECS_OPUS_AUDIO_DECODER_MULTI_CHANNEL_OPUS_CONFIG_H_
+
+#include <vector>
+
+namespace webrtc {
+struct AudioDecoderMultiChannelOpusConfig {
+ // The number of channels that the decoder will output.
+ int num_channels;
+
+ // Number of mono or stereo encoded Opus streams.
+ int num_streams;
+
+ // Number of channel pairs coupled together, see RFC 7845 section
+ // 5.1.1. Has to be less than the number of streams.
+ int coupled_streams;
+
+ // Channel mapping table, defines the mapping from encoded streams to output
+ // channels. See RFC 7845 section 5.1.1.
+ std::vector<unsigned char> channel_mapping;
+
+ bool IsOk() const {
+ if (num_channels < 0 || num_streams < 0 || coupled_streams < 0) {
+ return false;
+ }
+ if (num_streams < coupled_streams) {
+ return false;
+ }
+ if (channel_mapping.size() != static_cast<size_t>(num_channels)) {
+ return false;
+ }
+
+ // Every mono stream codes one channel, every coupled stream codes two. This
+ // is the total coded channel count:
+ const int max_coded_channel = num_streams + coupled_streams;
+ for (const auto& x : channel_mapping) {
+ // Coded channels >= max_coded_channel don't exist. Except for 255, which
+ // tells Opus to put silence in output channel x.
+ if (x >= max_coded_channel && x != 255) {
+ return false;
+ }
+ }
+
+ if (num_channels > 255 || max_coded_channel >= 255) {
+ return false;
+ }
+ return true;
+ }
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_OPUS_AUDIO_DECODER_MULTI_CHANNEL_OPUS_CONFIG_H_