Skip to content

Commit

Permalink
Support dependency descriptor and two-byte header
Browse files Browse the repository at this point in the history
  • Loading branch information
melpon committed Mar 5, 2024
1 parent 437a758 commit 0f9a96e
Show file tree
Hide file tree
Showing 9 changed files with 626 additions and 40 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ set(LIBDATACHANNEL_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/channel.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/configuration.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/datachannel.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/dependencydescriptor.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/description.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/mediahandler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/global.cpp
Expand Down Expand Up @@ -93,6 +94,7 @@ set(LIBDATACHANNEL_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/channel.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/configuration.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/datachannel.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/dependencydescriptor.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/description.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/mediahandler.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/rtcpreceivingsession.hpp
Expand Down
103 changes: 103 additions & 0 deletions include/rtc/dependencydescriptor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/**
* Copyright (c) 2024 Shigemasa Watanabe (Wandbox)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

#ifndef RTC_DEPENDENCY_DESCRIPTOR_H
#define RTC_DEPENDENCY_DESCRIPTOR_H

#include <bitset>
#include <cassert>
#include <optional>
#include <vector>

namespace rtc {

struct BitWriter {
static BitWriter fromSizeBits(std::byte *buf, size_t offsetBits, size_t sizeBits);
static BitWriter fromNull();

size_t getWrittenBits() const;

bool write(uint64_t v, size_t bits);
// Write non-symmetric unsigned encoded integer
// ref: https://aomediacodec.github.io/av1-rtp-spec/#a82-syntax
bool writeNonSymmetric(uint64_t v, uint64_t n);

private:
size_t writePartialByte(uint8_t *p, size_t offset, uint64_t v, size_t bits);

private:
std::byte *mBuf = nullptr;
size_t mInitialOffset = 0;
size_t mOffset = 0;
size_t mSize = 0;
};

enum class DecodeTargetIndication {
NotPresent = 0,
Discardable = 1,
Switch = 2,
Required = 3,
};

struct RenderResolution {
int width = 0;
int height = 0;
};

struct FrameDependencyTemplate {
int spatialId = 0;
int temporalId = 0;
std::vector<DecodeTargetIndication> decodeTargetIndications;
std::vector<int> frameDiffs;
std::vector<int> chainDiffs;
};

struct FrameDependencyStructure {
int templateIdOffset = 0;
int decodeTargetCount = 0;
int chainCount = 0;
std::vector<int> decodeTargetProtectedBy;
std::vector<RenderResolution> resolutions;
std::vector<FrameDependencyTemplate> templates;
};

struct DependencyDescriptor {
bool startOfFrame = true;
bool endOfFrame = true;
int frameNumber = 0;
FrameDependencyTemplate dependencyTemplate;
std::optional<RenderResolution> resolution;
std::optional<uint32_t> activeDecodeTargetsBitmask;
bool structureAttached;
};

// Write dependency descriptor to RTP Header Extension
// Dependency descriptor specification is here:
// https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension
class DependencyDescriptorWriter {
public:
DependencyDescriptorWriter(const FrameDependencyStructure &structure,
std::bitset<32> activeChains,
const DependencyDescriptor &descriptor);
size_t getSizeBits() const;
void writeTo(std::byte *buf, size_t sizeBits) const;

private:
void doWriteTo(BitWriter &writer) const;
void writeBits(BitWriter &writer, uint64_t v, size_t bits) const;
void writeNonSymmetric(BitWriter &writer, uint64_t v, uint64_t n) const;

private:
const FrameDependencyStructure &mStructure;
std::bitset<32> mActiveChains;
const DependencyDescriptor &mDescriptor;
};

} // namespace rtc

#endif
1 change: 1 addition & 0 deletions include/rtc/rtc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

// Media
#include "av1rtppacketizer.hpp"
#include "dependencydescriptor.hpp"
#include "h264rtppacketizer.hpp"
#include "h264rtpdepacketizer.hpp"
#include "h265rtppacketizer.hpp"
Expand Down
6 changes: 4 additions & 2 deletions include/rtc/rtp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ struct RTC_CPP_EXPORT RtpExtensionHeader {
void setHeaderLength(uint16_t headerLength);

void clearBody();
void writeCurrentVideoOrientation(size_t offset, uint8_t id, uint8_t value);
void writeOneByteHeader(size_t offset, uint8_t id, const byte *value, size_t size);
int writeCurrentVideoOrientation(bool twoByteHeader, size_t offset, uint8_t id, uint8_t value);
int writeOneByteHeader(size_t offset, uint8_t id, const byte *value, size_t size);
int writeTwoByteHeader(size_t offset, uint8_t id, const byte *value, size_t size);
int writeHeader(bool twoByteHeader, size_t offset, uint8_t id, const byte *value, size_t size);
};

struct RTC_CPP_EXPORT RtpHeader {
Expand Down
10 changes: 10 additions & 0 deletions include/rtc/rtppacketizationconfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#if RTC_ENABLE_MEDIA

#include "dependencydescriptor.hpp"
#include "rtp.hpp"

namespace rtc {
Expand Down Expand Up @@ -61,6 +62,15 @@ class RTC_CPP_EXPORT RtpPacketizationConfig {
uint8_t ridId = 0;
optional<std::string> rid;

// Dependency Descriptor Extension Header
uint8_t dependencyDescriptorId = 0;
struct DependencyDescriptorContext {
DependencyDescriptor descriptor;
std::bitset<32> activeChains;
FrameDependencyStructure structure;
};
optional<DependencyDescriptorContext> dependencyDescriptorContext;

/// Construct RTP configuration used in packetization process
/// @param ssrc SSRC of source
/// @param cname CNAME of source
Expand Down
16 changes: 10 additions & 6 deletions src/av1rtppacketizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,7 @@ std::vector<binary_ptr> AV1RtpPacketizer::packetizeObu(binary_ptr message,
AV1RtpPacketizer::AV1RtpPacketizer(AV1RtpPacketizer::Packetization packetization,
shared_ptr<RtpPacketizationConfig> rtpConfig,
uint16_t maxFragmentSize)
: RtpPacketizer(rtpConfig), maxFragmentSize(maxFragmentSize),
packetization(packetization) {}
: RtpPacketizer(rtpConfig), maxFragmentSize(maxFragmentSize), packetization(packetization) {}

void AV1RtpPacketizer::outgoing(message_vector &messages,
[[maybe_unused]] const message_callback &send) {
Expand All @@ -211,10 +210,15 @@ void AV1RtpPacketizer::outgoing(message_vector &messages,
if (fragments.size() == 0)
continue;

for (size_t i = 0; i < fragments.size() - 1; i++)
result.push_back(packetize(fragments[i], false));

result.push_back(packetize(fragments[fragments.size() - 1], true));
for (size_t i = 0; i < fragments.size(); i++) {
if (rtpConfig->dependencyDescriptorContext.has_value()) {
auto &ctx = *rtpConfig->dependencyDescriptorContext;
ctx.descriptor.startOfFrame = i == 0;
ctx.descriptor.endOfFrame = i == fragments.size() - 1;
}
bool mark = i == fragments.size() - 1;
result.push_back(packetize(fragments[i], mark));
}
}

messages.swap(result);
Expand Down
Loading

0 comments on commit 0f9a96e

Please sign in to comment.