Skip to content

Commit 0f9a96e

Browse files
committed
Support dependency descriptor and two-byte header
1 parent 437a758 commit 0f9a96e

9 files changed

+626
-40
lines changed

CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ set(LIBDATACHANNEL_SOURCES
6363
${CMAKE_CURRENT_SOURCE_DIR}/src/channel.cpp
6464
${CMAKE_CURRENT_SOURCE_DIR}/src/configuration.cpp
6565
${CMAKE_CURRENT_SOURCE_DIR}/src/datachannel.cpp
66+
${CMAKE_CURRENT_SOURCE_DIR}/src/dependencydescriptor.cpp
6667
${CMAKE_CURRENT_SOURCE_DIR}/src/description.cpp
6768
${CMAKE_CURRENT_SOURCE_DIR}/src/mediahandler.cpp
6869
${CMAKE_CURRENT_SOURCE_DIR}/src/global.cpp
@@ -93,6 +94,7 @@ set(LIBDATACHANNEL_HEADERS
9394
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/channel.hpp
9495
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/configuration.hpp
9596
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/datachannel.hpp
97+
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/dependencydescriptor.hpp
9698
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/description.hpp
9799
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/mediahandler.hpp
98100
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/rtcpreceivingsession.hpp

include/rtc/dependencydescriptor.hpp

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
* Copyright (c) 2024 Shigemasa Watanabe (Wandbox)
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
7+
*/
8+
9+
#ifndef RTC_DEPENDENCY_DESCRIPTOR_H
10+
#define RTC_DEPENDENCY_DESCRIPTOR_H
11+
12+
#include <bitset>
13+
#include <cassert>
14+
#include <optional>
15+
#include <vector>
16+
17+
namespace rtc {
18+
19+
struct BitWriter {
20+
static BitWriter fromSizeBits(std::byte *buf, size_t offsetBits, size_t sizeBits);
21+
static BitWriter fromNull();
22+
23+
size_t getWrittenBits() const;
24+
25+
bool write(uint64_t v, size_t bits);
26+
// Write non-symmetric unsigned encoded integer
27+
// ref: https://aomediacodec.github.io/av1-rtp-spec/#a82-syntax
28+
bool writeNonSymmetric(uint64_t v, uint64_t n);
29+
30+
private:
31+
size_t writePartialByte(uint8_t *p, size_t offset, uint64_t v, size_t bits);
32+
33+
private:
34+
std::byte *mBuf = nullptr;
35+
size_t mInitialOffset = 0;
36+
size_t mOffset = 0;
37+
size_t mSize = 0;
38+
};
39+
40+
enum class DecodeTargetIndication {
41+
NotPresent = 0,
42+
Discardable = 1,
43+
Switch = 2,
44+
Required = 3,
45+
};
46+
47+
struct RenderResolution {
48+
int width = 0;
49+
int height = 0;
50+
};
51+
52+
struct FrameDependencyTemplate {
53+
int spatialId = 0;
54+
int temporalId = 0;
55+
std::vector<DecodeTargetIndication> decodeTargetIndications;
56+
std::vector<int> frameDiffs;
57+
std::vector<int> chainDiffs;
58+
};
59+
60+
struct FrameDependencyStructure {
61+
int templateIdOffset = 0;
62+
int decodeTargetCount = 0;
63+
int chainCount = 0;
64+
std::vector<int> decodeTargetProtectedBy;
65+
std::vector<RenderResolution> resolutions;
66+
std::vector<FrameDependencyTemplate> templates;
67+
};
68+
69+
struct DependencyDescriptor {
70+
bool startOfFrame = true;
71+
bool endOfFrame = true;
72+
int frameNumber = 0;
73+
FrameDependencyTemplate dependencyTemplate;
74+
std::optional<RenderResolution> resolution;
75+
std::optional<uint32_t> activeDecodeTargetsBitmask;
76+
bool structureAttached;
77+
};
78+
79+
// Write dependency descriptor to RTP Header Extension
80+
// Dependency descriptor specification is here:
81+
// https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension
82+
class DependencyDescriptorWriter {
83+
public:
84+
DependencyDescriptorWriter(const FrameDependencyStructure &structure,
85+
std::bitset<32> activeChains,
86+
const DependencyDescriptor &descriptor);
87+
size_t getSizeBits() const;
88+
void writeTo(std::byte *buf, size_t sizeBits) const;
89+
90+
private:
91+
void doWriteTo(BitWriter &writer) const;
92+
void writeBits(BitWriter &writer, uint64_t v, size_t bits) const;
93+
void writeNonSymmetric(BitWriter &writer, uint64_t v, uint64_t n) const;
94+
95+
private:
96+
const FrameDependencyStructure &mStructure;
97+
std::bitset<32> mActiveChains;
98+
const DependencyDescriptor &mDescriptor;
99+
};
100+
101+
} // namespace rtc
102+
103+
#endif

include/rtc/rtc.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
// Media
3131
#include "av1rtppacketizer.hpp"
32+
#include "dependencydescriptor.hpp"
3233
#include "h264rtppacketizer.hpp"
3334
#include "h264rtpdepacketizer.hpp"
3435
#include "h265rtppacketizer.hpp"

include/rtc/rtp.hpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ struct RTC_CPP_EXPORT RtpExtensionHeader {
3838
void setHeaderLength(uint16_t headerLength);
3939

4040
void clearBody();
41-
void writeCurrentVideoOrientation(size_t offset, uint8_t id, uint8_t value);
42-
void writeOneByteHeader(size_t offset, uint8_t id, const byte *value, size_t size);
41+
int writeCurrentVideoOrientation(bool twoByteHeader, size_t offset, uint8_t id, uint8_t value);
42+
int writeOneByteHeader(size_t offset, uint8_t id, const byte *value, size_t size);
43+
int writeTwoByteHeader(size_t offset, uint8_t id, const byte *value, size_t size);
44+
int writeHeader(bool twoByteHeader, size_t offset, uint8_t id, const byte *value, size_t size);
4345
};
4446

4547
struct RTC_CPP_EXPORT RtpHeader {

include/rtc/rtppacketizationconfig.hpp

+10
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#if RTC_ENABLE_MEDIA
1313

14+
#include "dependencydescriptor.hpp"
1415
#include "rtp.hpp"
1516

1617
namespace rtc {
@@ -61,6 +62,15 @@ class RTC_CPP_EXPORT RtpPacketizationConfig {
6162
uint8_t ridId = 0;
6263
optional<std::string> rid;
6364

65+
// Dependency Descriptor Extension Header
66+
uint8_t dependencyDescriptorId = 0;
67+
struct DependencyDescriptorContext {
68+
DependencyDescriptor descriptor;
69+
std::bitset<32> activeChains;
70+
FrameDependencyStructure structure;
71+
};
72+
optional<DependencyDescriptorContext> dependencyDescriptorContext;
73+
6474
/// Construct RTP configuration used in packetization process
6575
/// @param ssrc SSRC of source
6676
/// @param cname CNAME of source

src/av1rtppacketizer.cpp

+10-6
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,7 @@ std::vector<binary_ptr> AV1RtpPacketizer::packetizeObu(binary_ptr message,
188188
AV1RtpPacketizer::AV1RtpPacketizer(AV1RtpPacketizer::Packetization packetization,
189189
shared_ptr<RtpPacketizationConfig> rtpConfig,
190190
uint16_t maxFragmentSize)
191-
: RtpPacketizer(rtpConfig), maxFragmentSize(maxFragmentSize),
192-
packetization(packetization) {}
191+
: RtpPacketizer(rtpConfig), maxFragmentSize(maxFragmentSize), packetization(packetization) {}
193192

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

214-
for (size_t i = 0; i < fragments.size() - 1; i++)
215-
result.push_back(packetize(fragments[i], false));
216-
217-
result.push_back(packetize(fragments[fragments.size() - 1], true));
213+
for (size_t i = 0; i < fragments.size(); i++) {
214+
if (rtpConfig->dependencyDescriptorContext.has_value()) {
215+
auto &ctx = *rtpConfig->dependencyDescriptorContext;
216+
ctx.descriptor.startOfFrame = i == 0;
217+
ctx.descriptor.endOfFrame = i == fragments.size() - 1;
218+
}
219+
bool mark = i == fragments.size() - 1;
220+
result.push_back(packetize(fragments[i], mark));
221+
}
218222
}
219223

220224
messages.swap(result);

0 commit comments

Comments
 (0)