Skip to content

Commit 59ce380

Browse files
Merge pull request #1265 from paullouisageneau/sendframe
Add sendFrame() and refactor packetization
2 parents 7001da9 + 66ac4cb commit 59ce380

33 files changed

+576
-460
lines changed

examples/streamer/main.cpp

+4-17
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include "helpers.hpp"
2121
#include "ArgParser.hpp"
2222

23+
#include <chrono>
24+
2325
using namespace rtc;
2426
using namespace std;
2527
using namespace std::chrono_literals;
@@ -208,7 +210,7 @@ shared_ptr<ClientTrackData> addVideo(const shared_ptr<PeerConnection> pc, const
208210
video.addSSRC(ssrc, cname, msid, cname);
209211
auto track = pc->addTrack(video);
210212
// create RTP configuration
211-
auto rtpConfig = make_shared<RtpPacketizationConfig>(ssrc, cname, payloadType, H264RtpPacketizer::defaultClockRate);
213+
auto rtpConfig = make_shared<RtpPacketizationConfig>(ssrc, cname, payloadType, H264RtpPacketizer::ClockRate);
212214
// create packetizer
213215
auto packetizer = make_shared<H264RtpPacketizer>(NalUnit::Separator::Length, rtpConfig);
214216
// add RTCP SR handler
@@ -351,26 +353,11 @@ shared_ptr<Stream> createStream(const string h264Samples, const unsigned fps, co
351353
for (auto clientTrack: tracks) {
352354
auto client = clientTrack.id;
353355
auto trackData = clientTrack.trackData;
354-
auto rtpConfig = trackData->sender->rtpConfig;
355-
356-
// sample time is in us, we need to convert it to seconds
357-
auto elapsedSeconds = double(sampleTime) / (1000 * 1000);
358-
// get elapsed time in clock rate
359-
uint32_t elapsedTimestamp = rtpConfig->secondsToTimestamp(elapsedSeconds);
360-
// set new timestamp
361-
rtpConfig->timestamp = rtpConfig->startTimestamp + elapsedTimestamp;
362-
363-
// get elapsed time in clock rate from last RTCP sender report
364-
auto reportElapsedTimestamp = rtpConfig->timestamp - trackData->sender->lastReportedTimestamp();
365-
// check if last report was at least 1 second ago
366-
if (rtpConfig->timestampToSeconds(reportElapsedTimestamp) > 1) {
367-
trackData->sender->setNeedsToReport();
368-
}
369356

370357
cout << "Sending " << streamType << " sample with size: " << to_string(sample.size()) << " to " << client << endl;
371358
try {
372359
// send sample
373-
trackData->track->send(sample);
360+
trackData->track->sendFrame(sample, std::chrono::duration<double, std::micro>(sampleTime));
374361
} catch (const std::exception &e) {
375362
cerr << "Unable to send "<< streamType << " packet: " << e.what() << endl;
376363
}

include/rtc/av1rtppacketizer.hpp

+11-10
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ namespace rtc {
2020
// RTP packetization of AV1 payload
2121
class RTC_CPP_EXPORT AV1RtpPacketizer final : public RtpPacketizer {
2222
public:
23-
// Default clock rate for AV1 in RTP
24-
inline static const uint32_t defaultClockRate = 90 * 1000;
23+
inline static const uint32_t ClockRate = VideoClockRate;
24+
[[deprecated("Use ClockRate")]] inline static const uint32_t defaultClockRate = ClockRate;
2525

2626
// Define how OBUs are seperated in a AV1 Sample
2727
enum class Packetization {
@@ -33,17 +33,18 @@ class RTC_CPP_EXPORT AV1RtpPacketizer final : public RtpPacketizer {
3333
// @note RTP configuration is used in packetization process which may change some configuration
3434
// properties such as sequence number.
3535
AV1RtpPacketizer(Packetization packetization, shared_ptr<RtpPacketizationConfig> rtpConfig,
36-
uint16_t maxFragmentSize = NalUnits::defaultMaximumFragmentSize);
37-
38-
void outgoing(message_vector &messages, const message_callback &send) override;
36+
size_t maxFragmentSize = DefaultMaxFragmentSize);
3937

4038
private:
41-
shared_ptr<NalUnits> splitMessage(binary_ptr message);
42-
std::vector<shared_ptr<binary>> packetizeObu(binary_ptr message, uint16_t maxFragmentSize);
39+
static std::vector<binary> extractTemporalUnitObus(const binary &data);
40+
41+
std::vector<binary> fragment(binary data) override;
42+
std::vector<binary> fragmentObu(const binary &data);
43+
44+
const Packetization mPacketization;
45+
const size_t mMaxFragmentSize;
4346

44-
const uint16_t maxFragmentSize;
45-
const Packetization packetization;
46-
std::shared_ptr<binary> sequenceHeader;
47+
std::unique_ptr<binary> mSequenceHeader;
4748
};
4849

4950
// For backward compatibility, do not use

include/rtc/common.hpp

-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ using std::variant;
6767
using std::weak_ptr;
6868

6969
using binary = std::vector<byte>;
70-
using binary_ptr = shared_ptr<binary>;
7170
using message_variant = variant<binary, string>;
7271

7372
using std::int16_t;

include/rtc/frameinfo.hpp

+11-3
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,20 @@
1111

1212
#include "common.hpp"
1313

14+
#include <chrono>
15+
1416
namespace rtc {
1517

1618
struct RTC_CPP_EXPORT FrameInfo {
17-
FrameInfo(uint8_t payloadType, uint32_t timestamp) : payloadType(payloadType), timestamp(timestamp){};
18-
uint8_t payloadType; // Indicates codec of the frame
19-
uint32_t timestamp = 0; // RTP Timestamp
19+
FrameInfo(uint32_t timestamp) : timestamp(timestamp) {};
20+
template<typename Period = std::ratio<1>> FrameInfo(std::chrono::duration<double, Period> timestamp) : timestampSeconds(timestamp) {};
21+
22+
[[deprecated]] FrameInfo(uint8_t payloadType, uint32_t timestamp) : timestamp(timestamp), payloadType(payloadType) {};
23+
24+
uint32_t timestamp = 0;
25+
uint8_t payloadType = 0;
26+
27+
optional<std::chrono::duration<double>> timestampSeconds;
2028
};
2129

2230
} // namespace rtc

include/rtc/h264rtpdepacketizer.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class RTC_CPP_EXPORT H264RtpDepacketizer : public MediaHandler {
2727
public:
2828
using Separator = NalUnit::Separator;
2929

30+
inline static const uint32_t ClockRate = 90 * 1000;
31+
3032
H264RtpDepacketizer(Separator separator = Separator::LongStartSequence);
3133
virtual ~H264RtpDepacketizer() = default;
3234

include/rtc/h264rtppacketizer.hpp

+8-9
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ class RTC_CPP_EXPORT H264RtpPacketizer final : public RtpPacketizer {
2222
public:
2323
using Separator = NalUnit::Separator;
2424

25-
/// Default clock rate for H264 in RTP
26-
inline static const uint32_t defaultClockRate = 90 * 1000;
25+
inline static const uint32_t ClockRate = VideoClockRate;
26+
[[deprecated("Use ClockRate")]] inline static const uint32_t defaultClockRate = ClockRate;
2727

2828
/// Constructs h264 payload packetizer with given RTP configuration.
2929
/// @note RTP configuration is used in packetization process which may change some configuration
@@ -32,20 +32,19 @@ class RTC_CPP_EXPORT H264RtpPacketizer final : public RtpPacketizer {
3232
/// @param rtpConfig RTP configuration
3333
/// @param maxFragmentSize maximum size of one NALU fragment
3434
H264RtpPacketizer(Separator separator, shared_ptr<RtpPacketizationConfig> rtpConfig,
35-
uint16_t maxFragmentSize = NalUnits::defaultMaximumFragmentSize);
35+
size_t maxFragmentSize = DefaultMaxFragmentSize);
3636

3737
// For backward compatibility, do not use
3838
[[deprecated]] H264RtpPacketizer(
3939
shared_ptr<RtpPacketizationConfig> rtpConfig,
40-
uint16_t maxFragmentSize = NalUnits::defaultMaximumFragmentSize);
41-
42-
void outgoing(message_vector &messages, const message_callback &send) override;
40+
size_t maxFragmentSize = DefaultMaxFragmentSize);
4341

4442
private:
45-
shared_ptr<NalUnits> splitMessage(binary_ptr message);
43+
std::vector<binary> fragment(binary data) override;
44+
std::vector<NalUnit> splitFrame(const binary &frame);
4645

47-
const uint16_t maxFragmentSize;
48-
const Separator separator;
46+
const Separator mSeparator;
47+
const size_t mMaxFragmentSize;
4948
};
5049

5150
// For backward compatibility, do not use

include/rtc/h265nalunit.hpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "nalunit.hpp"
1616

1717
#include <cassert>
18+
#include <vector>
1819

1920
namespace rtc {
2021

@@ -72,8 +73,13 @@ struct RTC_CPP_EXPORT H265NalUnitFragmentHeader {
7273

7374
#pragma pack(pop)
7475

75-
/// Nal unit
76+
struct H265NalUnitFragment;
77+
78+
/// NAL unit
7679
struct RTC_CPP_EXPORT H265NalUnit : NalUnit {
80+
static std::vector<binary> GenerateFragments(const std::vector<H265NalUnit> &nalus,
81+
size_t maxFragmentSize);
82+
7783
H265NalUnit(const H265NalUnit &unit) = default;
7884
H265NalUnit(size_t size, bool includingHeader = true)
7985
: NalUnit(size, includingHeader, NalUnit::Type::H265) {}
@@ -104,6 +110,8 @@ struct RTC_CPP_EXPORT H265NalUnit : NalUnit {
104110
insert(end(), payload.begin(), payload.end());
105111
}
106112

113+
std::vector<H265NalUnitFragment> generateFragments(size_t maxFragmentSize) const;
114+
107115
protected:
108116
const H265NalUnitHeader *header() const {
109117
assert(size() >= H265_NAL_HEADER_SIZE);
@@ -116,9 +124,9 @@ struct RTC_CPP_EXPORT H265NalUnit : NalUnit {
116124
}
117125
};
118126

119-
/// Nal unit fragment A
127+
/// NAL unit fragment
120128
struct RTC_CPP_EXPORT H265NalUnitFragment : H265NalUnit {
121-
static std::vector<shared_ptr<H265NalUnitFragment>> fragmentsFrom(shared_ptr<H265NalUnit> nalu,
129+
[[deprecated]] static std::vector<shared_ptr<H265NalUnitFragment>> fragmentsFrom(shared_ptr<H265NalUnit> nalu,
122130
uint16_t maxFragmentSize);
123131

124132
enum class FragmentType { Start, Middle, End };
@@ -171,7 +179,7 @@ struct RTC_CPP_EXPORT H265NalUnitFragment : H265NalUnit {
171179
}
172180
};
173181

174-
class RTC_CPP_EXPORT H265NalUnits : public std::vector<shared_ptr<H265NalUnit>> {
182+
class [[deprecated]] RTC_CPP_EXPORT H265NalUnits : public std::vector<shared_ptr<H265NalUnit>> {
175183
public:
176184
static const uint16_t defaultMaximumFragmentSize =
177185
uint16_t(RTC_DEFAULT_MTU - 12 - 8 - 40); // SRTP/UDP/IPv6

include/rtc/h265rtpdepacketizer.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class RTC_CPP_EXPORT H265RtpDepacketizer : public MediaHandler {
2828
public:
2929
using Separator = NalUnit::Separator;
3030

31+
inline static const uint32_t ClockRate = 90 * 1000;
32+
3133
H265RtpDepacketizer(Separator separator = Separator::LongStartSequence);
3234
virtual ~H265RtpDepacketizer() = default;
3335

include/rtc/h265rtppacketizer.hpp

+9-10
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ class RTC_CPP_EXPORT H265RtpPacketizer final : public RtpPacketizer {
2121
public:
2222
using Separator = NalUnit::Separator;
2323

24-
// Default clock rate for H265 in RTP
25-
inline static const uint32_t defaultClockRate = 90 * 1000;
24+
inline static const uint32_t ClockRate = VideoClockRate;
25+
[[deprecated("Use ClockRate")]] inline static const uint32_t defaultClockRate = ClockRate;
2626

2727
// Constructs h265 payload packetizer with given RTP configuration.
2828
// @note RTP configuration is used in packetization process which may change some configuration
@@ -31,19 +31,18 @@ class RTC_CPP_EXPORT H265RtpPacketizer final : public RtpPacketizer {
3131
// @param rtpConfig RTP configuration
3232
// @param maxFragmentSize maximum size of one NALU fragment
3333
H265RtpPacketizer(Separator separator, shared_ptr<RtpPacketizationConfig> rtpConfig,
34-
uint16_t maxFragmentSize = H265NalUnits::defaultMaximumFragmentSize);
34+
size_t maxFragmentSize = DefaultMaxFragmentSize);
3535

36-
// for backward compatibility
36+
// For backward compatibility, do not use
3737
[[deprecated]] H265RtpPacketizer(shared_ptr<RtpPacketizationConfig> rtpConfig,
38-
uint16_t maxFragmentSize = H265NalUnits::defaultMaximumFragmentSize);
39-
40-
void outgoing(message_vector &messages, const message_callback &send) override;
38+
size_t maxFragmentSize = DefaultMaxFragmentSize);
4139

4240
private:
43-
shared_ptr<H265NalUnits> splitMessage(binary_ptr message);
41+
std::vector<binary> fragment(binary data) override;
42+
std::vector<H265NalUnit> splitFrame(const binary &frame);
4443

45-
const uint16_t maxFragmentSize;
46-
const NalUnit::Separator separator;
44+
const NalUnit::Separator mSeparator;
45+
const size_t mMaxFragmentSize;
4746
};
4847

4948
// For backward compatibility, do not use

include/rtc/message.hpp

+20-4
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,26 @@ inline size_t message_size_func(const message_ptr &m) {
4646

4747
template <typename Iterator>
4848
message_ptr make_message(Iterator begin, Iterator end, Message::Type type = Message::Binary,
49-
unsigned int stream = 0, shared_ptr<Reliability> reliability = nullptr,
50-
shared_ptr<FrameInfo> frameInfo = nullptr) {
49+
unsigned int stream = 0, shared_ptr<Reliability> reliability = nullptr) {
5150
auto message = std::make_shared<Message>(begin, end, type);
5251
message->stream = stream;
5352
message->reliability = reliability;
53+
return message;
54+
}
55+
56+
template <typename Iterator>
57+
message_ptr make_message(Iterator begin, Iterator end, shared_ptr<FrameInfo> frameInfo) {
58+
auto message = std::make_shared<Message>(begin, end);
59+
message->frameInfo = frameInfo;
60+
return message;
61+
}
62+
63+
// For backward compatibiity, do not use
64+
template <typename Iterator>
65+
[[deprecated]] message_ptr make_message(Iterator begin, Iterator end, Message::Type type,
66+
unsigned int stream, shared_ptr<FrameInfo> frameInfo) {
67+
auto message = std::make_shared<Message>(begin, end, type);
68+
message->stream = stream;
5469
message->frameInfo = frameInfo;
5570
return message;
5671
}
@@ -61,8 +76,9 @@ RTC_CPP_EXPORT message_ptr make_message(size_t size, Message::Type type = Messag
6176

6277
RTC_CPP_EXPORT message_ptr make_message(binary &&data, Message::Type type = Message::Binary,
6378
unsigned int stream = 0,
64-
shared_ptr<Reliability> reliability = nullptr,
65-
shared_ptr<FrameInfo> frameInfo = nullptr);
79+
shared_ptr<Reliability> reliability = nullptr);
80+
81+
RTC_CPP_EXPORT message_ptr make_message(binary &&data, shared_ptr<FrameInfo> frameInfo);
6682

6783
RTC_CPP_EXPORT message_ptr make_message(size_t size, message_ptr orig);
6884

0 commit comments

Comments
 (0)