#ifndef MS_RTC_RTP_CODECS_DEPENDENCY_DESCRIPTOR_HPP
#define MS_RTC_RTP_CODECS_DEPENDENCY_DESCRIPTOR_HPP
#include "common.hpp"
#include "Utils.hpp"
#include <ankerl/unordered_dense.h>
namespace RTC
{
namespace RTP
{
namespace Codecs
{
struct DependencyDescriptor
{
class Listener
{
public:
virtual ~Listener() = default;
public:
virtual void OnDependencyDescriptorUpdated(const uint8_t* data, size_t len) = 0;
};
public:
enum class DecodeTargetIndication : uint8_t
{
NOT_PRESENT = 0,
DISCARDABLE = 1,
SWITCH = 2,
REQUIRED = 3
};
private:
static ankerl::unordered_dense::map<DecodeTargetIndication, std::string> dtiToString;
private:
struct FrameDependencyTemplate
{
FrameDependencyTemplate(uint32_t spatialLayer, uint32_t temporalLayer)
: spatialLayer(spatialLayer), temporalLayer(temporalLayer)
{
}
uint32_t spatialLayer;
uint32_t temporalLayer;
std::vector<DecodeTargetIndication> decodeTargetIndications;
std::vector<uint8_t> frameDiffs;
std::vector<uint8_t> frameDiffChains;
};
public:
struct TemplateDependencyStructure
{
uint32_t spatialLayers{ 0 };
uint32_t temporalLayers{ 0 };
uint8_t templateIdOffset{ 0 };
uint8_t decodeTargetCount{ 0 };
std::vector<FrameDependencyTemplate> templateLayers;
};
public:
bool startOfFrame{ false };
bool endOfFrame{ false };
uint8_t frameDependencyTemplateId{ 0 };
uint16_t frameNumber{ 0 };
uint8_t templateId{ 0 };
TemplateDependencyStructure* templateDependencyStructure;
std::vector<uint8_t> decodeTargetProtectedBy;
std::optional<uint32_t> activeDecodeTargetsBitmask{ std::nullopt };
uint8_t temporalLayer{ 0 };
uint8_t spatialLayer{ 0 };
bool isKeyFrame{ false };
private:
DependencyDescriptor::Listener* listener{ nullptr };
public:
static DependencyDescriptor* Parse(
const uint8_t* data,
size_t len,
DependencyDescriptor::Listener* listener,
std::unique_ptr<TemplateDependencyStructure>& templateDependencyStructure);
DependencyDescriptor(
const uint8_t* data,
size_t len,
DependencyDescriptor::Listener* listener,
TemplateDependencyStructure* templateDependencyStructure);
void Dump(int indentation = 0) const;
void UpdateListener(DependencyDescriptor::Listener* listener);
const uint8_t* Serialize(uint8_t& len);
bool UpdateActiveDecodeTargets(uint32_t maxSpatialLayer, uint32_t maxTemporalLayer);
private:
uint8_t GetSpatialLayer() const;
uint8_t GetTemporalLayer() const;
bool ReadMandatoryDescriptorFields();
bool ReadExtendedDescriptorFields();
bool ReadTemplateDependencyStructure();
bool ReadTemplateLayers();
bool ReadTemplateDecodeTargetIndications();
bool ReadTemplateFrameDiffs();
bool ReadTemplateFrameDiffChains();
bool ReadFrameDependencyDefinition();
bool WriteMandatoryDescriptorFields();
bool WriteExtendedDescriptorFields();
private:
Utils::BitStream bitStream;
};
} } }
#endif