Audio codec factories: Pass a codec pair ID to new codecs
Currently ignored by all implementations and callers, but future CLs will remedy that. Bug: webrtc:8941 Change-Id: I59a3af78fefcf35af3e5ef37d2adf1165ce5751e Reviewed-on: https://webrtc-review.googlesource.com/58080 Reviewed-by: Oskar Sundbom <ossu@webrtc.org> Commit-Queue: Karl Wiberg <kwiberg@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22248}
This commit is contained in:
parent
f4e99dba41
commit
98900740ad
@ -15,12 +15,16 @@ if (is_android) {
|
||||
rtc_source_set("audio_codecs_api") {
|
||||
visibility = [ "*" ]
|
||||
sources = [
|
||||
"audio_codec_pair_id.cc",
|
||||
"audio_codec_pair_id.h",
|
||||
"audio_decoder.cc",
|
||||
"audio_decoder.h",
|
||||
"audio_decoder_factory.cc",
|
||||
"audio_decoder_factory.h",
|
||||
"audio_decoder_factory_template.h",
|
||||
"audio_encoder.cc",
|
||||
"audio_encoder.h",
|
||||
"audio_encoder_factory.cc",
|
||||
"audio_encoder_factory.h",
|
||||
"audio_encoder_factory_template.h",
|
||||
"audio_format.cc",
|
||||
|
||||
90
api/audio_codecs/audio_codec_pair_id.cc
Normal file
90
api/audio_codecs/audio_codec_pair_id.cc
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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/audio_codec_pair_id.h"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
// Returns a new value that it has never returned before. You may call it at
|
||||
// most 2^63 times in the lifetime of the program. Note: The returned values
|
||||
// may be easily predictable.
|
||||
uint64_t GetNextId() {
|
||||
static std::atomic<uint64_t> next_id(0);
|
||||
|
||||
// Atomically increment `next_id`, and return the previous value. Relaxed
|
||||
// memory order is sufficient, since all we care about is that different
|
||||
// callers return different values.
|
||||
const uint64_t new_id = next_id.fetch_add(1, std::memory_order_relaxed);
|
||||
|
||||
// This check isn't atomic with the increment, so if we start 2^63 + 1
|
||||
// invocations of GetNextId() in parallel, the last one to do the atomic
|
||||
// increment could return the ID 0 before any of the others had time to
|
||||
// trigger this DCHECK. We blithely assume that this won't happen.
|
||||
RTC_DCHECK_LT(new_id, uint64_t{1} << 63) << "Used up all ID values";
|
||||
|
||||
return new_id;
|
||||
}
|
||||
|
||||
// Make an integer ID more unpredictable. This is a 1:1 mapping, so you can
|
||||
// feed it any value, but the idea is that you can feed it a sequence such as
|
||||
// 0, 1, 2, ... and get a new sequence that isn't as trivially predictable, so
|
||||
// that users won't rely on it being consecutive or increasing or anything like
|
||||
// that.
|
||||
constexpr uint64_t ObfuscateId(uint64_t id) {
|
||||
// Any nonzero coefficient that's relatively prime to 2^64 (that is, any odd
|
||||
// number) and any constant will give a 1:1 mapping. These high-entropy
|
||||
// values will prevent the sequence from being trivially predictable.
|
||||
//
|
||||
// Both the multiplication and the addition going to overflow almost always,
|
||||
// but that's fine---we *want* arithmetic mod 2^64.
|
||||
return uint64_t{0x85fdb20e1294309a} + uint64_t{0xc516ef5c37462469} * id;
|
||||
}
|
||||
|
||||
// The first ten values. Verified against the Python function
|
||||
//
|
||||
// def f(n):
|
||||
// return (0x85fdb20e1294309a + 0xc516ef5c37462469 * n) % 2**64
|
||||
//
|
||||
// Callers should obviously not depend on these exact values...
|
||||
//
|
||||
// (On Visual C++, we have to disable warning C4307 (integral constant
|
||||
// overflow), even though unsigned integers have perfectly well-defined
|
||||
// overflow behavior.)
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4307)
|
||||
#endif
|
||||
static_assert(ObfuscateId(0) == uint64_t{0x85fdb20e1294309a}, "");
|
||||
static_assert(ObfuscateId(1) == uint64_t{0x4b14a16a49da5503}, "");
|
||||
static_assert(ObfuscateId(2) == uint64_t{0x102b90c68120796c}, "");
|
||||
static_assert(ObfuscateId(3) == uint64_t{0xd5428022b8669dd5}, "");
|
||||
static_assert(ObfuscateId(4) == uint64_t{0x9a596f7eefacc23e}, "");
|
||||
static_assert(ObfuscateId(5) == uint64_t{0x5f705edb26f2e6a7}, "");
|
||||
static_assert(ObfuscateId(6) == uint64_t{0x24874e375e390b10}, "");
|
||||
static_assert(ObfuscateId(7) == uint64_t{0xe99e3d93957f2f79}, "");
|
||||
static_assert(ObfuscateId(8) == uint64_t{0xaeb52cefccc553e2}, "");
|
||||
static_assert(ObfuscateId(9) == uint64_t{0x73cc1c4c040b784b}, "");
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
AudioCodecPairId AudioCodecPairId::Create() {
|
||||
return AudioCodecPairId(ObfuscateId(GetNextId()));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
74
api/audio_codecs/audio_codec_pair_id.h
Normal file
74
api/audio_codecs/audio_codec_pair_id.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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_AUDIO_CODEC_PAIR_ID_H_
|
||||
#define API_AUDIO_CODECS_AUDIO_CODEC_PAIR_ID_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class AudioCodecPairId final {
|
||||
public:
|
||||
// Copyable, but not default constructible.
|
||||
AudioCodecPairId() = delete;
|
||||
AudioCodecPairId(const AudioCodecPairId&) = default;
|
||||
AudioCodecPairId(AudioCodecPairId&&) = default;
|
||||
AudioCodecPairId& operator=(const AudioCodecPairId&) = default;
|
||||
AudioCodecPairId& operator=(AudioCodecPairId&&) = default;
|
||||
|
||||
friend void swap(AudioCodecPairId& a, AudioCodecPairId& b) {
|
||||
using std::swap;
|
||||
swap(a.id_, b.id_);
|
||||
}
|
||||
|
||||
// Creates a new ID, unequal to any previously created ID.
|
||||
static AudioCodecPairId Create();
|
||||
|
||||
// IDs can be tested for equality.
|
||||
friend bool operator==(AudioCodecPairId a, AudioCodecPairId b) {
|
||||
return a.id_ == b.id_;
|
||||
}
|
||||
friend bool operator!=(AudioCodecPairId a, AudioCodecPairId b) {
|
||||
return a.id_ != b.id_;
|
||||
}
|
||||
|
||||
// Comparisons. The ordering of ID values is completely arbitrary, but
|
||||
// stable, so it's useful e.g. if you want to use IDs as keys in an ordered
|
||||
// map.
|
||||
friend bool operator<(AudioCodecPairId a, AudioCodecPairId b) {
|
||||
return a.id_ < b.id_;
|
||||
}
|
||||
friend bool operator<=(AudioCodecPairId a, AudioCodecPairId b) {
|
||||
return a.id_ <= b.id_;
|
||||
}
|
||||
friend bool operator>=(AudioCodecPairId a, AudioCodecPairId b) {
|
||||
return a.id_ >= b.id_;
|
||||
}
|
||||
friend bool operator>(AudioCodecPairId a, AudioCodecPairId b) {
|
||||
return a.id_ > b.id_;
|
||||
}
|
||||
|
||||
// Returns a numeric representation of the ID. The numeric values are
|
||||
// completely arbitrary, but stable, collision-free, and reasonably evenly
|
||||
// distributed, so they are e.g. useful as hash values in unordered maps.
|
||||
uint64_t NumericRepresentation() const { return id_; }
|
||||
|
||||
private:
|
||||
explicit AudioCodecPairId(uint64_t id) : id_(id) {}
|
||||
|
||||
uint64_t id_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_AUDIO_CODECS_AUDIO_CODEC_PAIR_ID_H_
|
||||
26
api/audio_codecs/audio_decoder_factory.cc
Normal file
26
api/audio_codecs/audio_decoder_factory.cc
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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/audio_decoder_factory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::unique_ptr<AudioDecoder> AudioDecoderFactory::MakeAudioDecoder(
|
||||
const SdpAudioFormat& format,
|
||||
rtc::Optional<AudioCodecPairId> codec_pair_id) {
|
||||
return MakeAudioDecoder(format);
|
||||
}
|
||||
|
||||
std::unique_ptr<AudioDecoder> AudioDecoderFactory::MakeAudioDecoder(
|
||||
const SdpAudioFormat& format) {
|
||||
return MakeAudioDecoder(format, rtc::nullopt);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
@ -14,8 +14,10 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#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/optional.h"
|
||||
#include "rtc_base/refcount.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -28,8 +30,22 @@ class AudioDecoderFactory : public rtc::RefCountInterface {
|
||||
|
||||
virtual bool IsSupportedDecoder(const SdpAudioFormat& format) = 0;
|
||||
|
||||
// Create a new decoder instance. The `codec_pair_id` argument is used to
|
||||
// link encoders and decoders that talk to the same remote entity; if a
|
||||
// MakeAudioEncoder() and a MakeAudioDecoder() call receive non-null IDs that
|
||||
// compare equal, the factory implementations may assume that the encoder and
|
||||
// decoder form a pair.
|
||||
//
|
||||
// Note: Implementations need to be robust against combinations other than
|
||||
// one encoder, one decoder getting the same ID; such decoders must still
|
||||
// work.
|
||||
virtual std::unique_ptr<AudioDecoder> MakeAudioDecoder(
|
||||
const SdpAudioFormat& format) = 0;
|
||||
const SdpAudioFormat& format,
|
||||
rtc::Optional<AudioCodecPairId> codec_pair_id);
|
||||
|
||||
// Deprecated version of the above.
|
||||
virtual std::unique_ptr<AudioDecoder> MakeAudioDecoder(
|
||||
const SdpAudioFormat& format);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
28
api/audio_codecs/audio_encoder_factory.cc
Normal file
28
api/audio_codecs/audio_encoder_factory.cc
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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/audio_encoder_factory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::unique_ptr<AudioEncoder> AudioEncoderFactory::MakeAudioEncoder(
|
||||
int payload_type,
|
||||
const SdpAudioFormat& format,
|
||||
rtc::Optional<AudioCodecPairId> codec_pair_id) {
|
||||
return MakeAudioEncoder(payload_type, format);
|
||||
}
|
||||
|
||||
std::unique_ptr<AudioEncoder> AudioEncoderFactory::MakeAudioEncoder(
|
||||
int payload_type,
|
||||
const SdpAudioFormat& format) {
|
||||
return MakeAudioEncoder(payload_type, format, rtc::nullopt);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
@ -14,8 +14,10 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "api/audio_codecs/audio_codec_pair_id.h"
|
||||
#include "api/audio_codecs/audio_encoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "api/optional.h"
|
||||
#include "rtc_base/refcount.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -33,12 +35,27 @@ class AudioEncoderFactory : public rtc::RefCountInterface {
|
||||
virtual rtc::Optional<AudioCodecInfo> QueryAudioEncoder(
|
||||
const SdpAudioFormat& format) = 0;
|
||||
|
||||
// Creates an AudioEncoder for the specified format. The encoder will tags its
|
||||
// payloads with the specified payload type.
|
||||
// Creates an AudioEncoder for the specified format. The encoder will tags
|
||||
// its payloads with the specified payload type. The `codec_pair_id` argument
|
||||
// is used to link encoders and decoders that talk to the same remote entity;
|
||||
// if a MakeAudioEncoder() and a MakeAudioDecoder() call receive non-null IDs
|
||||
// that compare equal, the factory implementations may assume that the
|
||||
// encoder and decoder form a pair.
|
||||
//
|
||||
// Note: Implementations need to be robust against combinations other than
|
||||
// one encoder, one decoder getting the same ID; such encoders must still
|
||||
// work.
|
||||
//
|
||||
// TODO(ossu): Try to avoid audio encoders having to know their payload type.
|
||||
virtual std::unique_ptr<AudioEncoder> MakeAudioEncoder(
|
||||
int payload_type,
|
||||
const SdpAudioFormat& format) = 0;
|
||||
const SdpAudioFormat& format,
|
||||
rtc::Optional<AudioCodecPairId> codec_pair_id);
|
||||
|
||||
// Deprecated version of the above.
|
||||
virtual std::unique_ptr<AudioEncoder> MakeAudioEncoder(
|
||||
int payload_type,
|
||||
const SdpAudioFormat& format);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user