blob: 6f87f906d4e1b73c91eb88d0d5018aaf12ca6f48 [file]
/*
* Copyright (c) 2024 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 MEDIA_BASE_CODEC_LIST_H_
#define MEDIA_BASE_CODEC_LIST_H_
#include <cstddef>
#include <span>
#include <vector>
#include "api/rtc_error.h"
#include "media/base/codec.h"
namespace webrtc {
class CodecList {
public:
using iterator = std::vector<Codec>::iterator;
using const_iterator = std::vector<Codec>::const_iterator;
using value_type = Codec;
CodecList() = default;
// Copy and assign are available.
CodecList(const CodecList&) = default;
CodecList& operator=(const CodecList&) = default;
CodecList(CodecList&&) = default;
CodecList& operator=(CodecList&&) = default;
bool operator==(const CodecList& o) const { return codecs_ == o.codecs_; }
// Creates a codec list on untrusted data. If successful, the
// resulting CodecList satisfies all the CodecList invariants.
static RTCErrorOr<CodecList> Create(std::span<const Codec> codecs);
// Creates a codec list on trusted data. Only for use when
// the codec list is generated from internal code.
static CodecList CreateFromTrustedData(std::span<const Codec> codecs) {
return CodecList(codecs);
}
// The outcome of PushIfNotPresent().
enum class PushResult {
// The codec was added to the list.
kInserted,
// The exact same codec was already in the list; the list is unchanged.
kDuplicate,
// A different codec with the same payload type was already in the list.
// The list is unchanged and an error is logged. This means that the
// caller combined codecs that come from different payload type mappings,
// which is a programming error.
kConflict,
};
// Inserts a codec into the list if no codec with the same payload type is
// present. The payload types in the list are kept unique; the codec that is
// already in the list is never replaced.
[[nodiscard]] PushResult PushIfNotPresent(const Codec& codec);
// Vector-compatible API to access the codecs.
iterator begin() { return codecs_.begin(); }
iterator end() { return codecs_.end(); }
const_iterator begin() const { return codecs_.begin(); }
const_iterator end() const { return codecs_.end(); }
const Codec& operator[](size_t i) const { return codecs_[i]; }
Codec& operator[](size_t i) { return codecs_[i]; }
// Appends a codec to the list. Payload types must remain unique. Note that
// an RTX codec may be added before the codec that it refers to, so the check
// that referenced codecs exist is left to CheckConsistency().
void push_back(const Codec& codec);
bool empty() const { return codecs_.empty(); }
void clear() { codecs_.clear(); }
size_t size() const { return codecs_.size(); }
// Access to the whole codec list
const std::vector<Codec>& codecs() const { return codecs_; }
std::vector<Codec>& writable_codecs() { return codecs_; }
// Verify consistency of a complete codec list.
// Examples: checking that all RTX codecs have APT pointing
// to a codec in the list.
// The function will CHECK or DCHECK on inconsistencies. It must only be
// called once the list is fully assembled.
void CheckConsistency();
// Marks the list as complete and moves the codecs out of it.
//
// This verifies the invariants that only hold for a complete list, such as
// every RTX codec referring to a codec that is present, and returns an error
// if they are violated. Use this rather than codecs() when handing the
// codecs to a caller, so that the verification cannot be forgotten. Unlike
// CheckConsistency(), an inconsistent list is reported as an error instead
// of being fatal, since a list can become inconsistent as the result of the
// codecs an application supplied.
//
// The CodecList is left empty, whether or not the check succeeded.
[[nodiscard]] RTCErrorOr<std::vector<Codec>> Finalize() &&;
template <typename Sink>
friend void AbslStringify(Sink& sink, const CodecList& list) {
absl::Format(&sink, "\n--- Codec list of size %d\n", list.size());
for (Codec codec : list) {
absl::Format(&sink, "%v\n", codec);
}
sink.Append("--- End\n");
}
private:
// Creates a codec list on trusted data.
explicit CodecList(std::span<const Codec> codecs)
: codecs_(codecs.begin(), codecs.end()) {
CheckConsistency();
}
std::vector<Codec> codecs_;
};
} // namespace webrtc
#endif // MEDIA_BASE_CODEC_LIST_H_