webrtc/modules/audio_coding/codecs/opus/audio_coder_opus_common.h
Alex Loiko e5b94160b5 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}
2019-04-08 16:15:37 +00:00

88 lines
2.8 KiB
C++

/*
* 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 MODULES_AUDIO_CODING_CODECS_OPUS_AUDIO_CODER_OPUS_COMMON_H_
#define MODULES_AUDIO_CODING_CODECS_OPUS_AUDIO_CODER_OPUS_COMMON_H_
#include <string>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "api/audio_codecs/audio_decoder.h"
#include "api/audio_codecs/audio_format.h"
#include "rtc_base/string_to_number.h"
namespace webrtc {
absl::optional<std::string> GetFormatParameter(const SdpAudioFormat& format,
const std::string& param);
template <typename T>
absl::optional<T> GetFormatParameter(const SdpAudioFormat& format,
const std::string& param) {
return rtc::StringToNumber<T>(GetFormatParameter(format, param).value_or(""));
}
template <>
absl::optional<std::vector<unsigned char>> GetFormatParameter(
const SdpAudioFormat& format,
const std::string& param);
class OpusFrame : public AudioDecoder::EncodedAudioFrame {
public:
OpusFrame(AudioDecoder* decoder,
rtc::Buffer&& payload,
bool is_primary_payload)
: decoder_(decoder),
payload_(std::move(payload)),
is_primary_payload_(is_primary_payload) {}
size_t Duration() const override {
int ret;
if (is_primary_payload_) {
ret = decoder_->PacketDuration(payload_.data(), payload_.size());
} else {
ret = decoder_->PacketDurationRedundant(payload_.data(), payload_.size());
}
return (ret < 0) ? 0 : static_cast<size_t>(ret);
}
bool IsDtxPacket() const override { return payload_.size() <= 2; }
absl::optional<DecodeResult> Decode(
rtc::ArrayView<int16_t> decoded) const override {
AudioDecoder::SpeechType speech_type = AudioDecoder::kSpeech;
int ret;
if (is_primary_payload_) {
ret = decoder_->Decode(
payload_.data(), payload_.size(), decoder_->SampleRateHz(),
decoded.size() * sizeof(int16_t), decoded.data(), &speech_type);
} else {
ret = decoder_->DecodeRedundant(
payload_.data(), payload_.size(), decoder_->SampleRateHz(),
decoded.size() * sizeof(int16_t), decoded.data(), &speech_type);
}
if (ret < 0)
return absl::nullopt;
return DecodeResult{static_cast<size_t>(ret), speech_type};
}
private:
AudioDecoder* const decoder_;
const rtc::Buffer payload_;
const bool is_primary_payload_;
};
} // namespace webrtc
#endif // MODULES_AUDIO_CODING_CODECS_OPUS_AUDIO_CODER_OPUS_COMMON_H_