Jelajahi Sumber

Adapted streamer example

Paul-Louis Ageneau 2 tahun lalu
induk
melakukan
589634670b

+ 21 - 2
examples/streamer/fileparser.cpp

@@ -21,10 +21,15 @@
 
 using namespace std;
 
-FileParser::FileParser(string directory, string extension, uint32_t samplesPerSecond, bool loop): sampleDuration_us(1000 * 1000 / samplesPerSecond), StreamSource() {
+FileParser::FileParser(string directory, string extension, uint32_t samplesPerSecond, bool loop) {
     this->directory = directory;
     this->extension = extension;
     this->loop = loop;
+    this->sampleDuration_us = 1000 * 1000 / samplesPerSecond;
+}
+
+FileParser::~FileParser() {
+	stop();
 }
 
 void FileParser::start() {
@@ -33,7 +38,8 @@ void FileParser::start() {
 }
 
 void FileParser::stop() {
-    StreamSource::stop();
+    sample = {};
+    sampleTime_us = 0;
     counter = -1;
 }
 
@@ -57,3 +63,16 @@ void FileParser::loadNextSample() {
     sample = *reinterpret_cast<vector<byte> *>(&fileContents);
     sampleTime_us += sampleDuration_us;
 }
+
+rtc::binary FileParser::getSample() {
+	return sample;
+}
+
+uint64_t FileParser::getSampleTime_us() {
+	return sampleTime_us;
+}
+
+uint64_t FileParser::getSampleDuration_us() {
+	return sampleDuration_us;
+}
+

+ 12 - 4
examples/streamer/fileparser.hpp

@@ -26,15 +26,23 @@
 class FileParser: public StreamSource {
     std::string directory;
     std::string extension;
+    uint64_t sampleDuration_us;
+    uint64_t sampleTime_us = 0;
     uint32_t counter = -1;
     bool loop;
     uint64_t loopTimestampOffset = 0;
+protected:
+    rtc::binary sample = {};
 public:
-    const uint64_t sampleDuration_us;
-    virtual void start();
-    virtual void stop();
     FileParser(std::string directory, std::string extension, uint32_t samplesPerSecond, bool loop);
-    virtual void loadNextSample();
+    virtual ~FileParser();
+    virtual void start() override;
+    virtual void stop() override;
+    virtual void loadNextSample() override;
+
+    rtc::binary getSample() override;
+    uint64_t getSampleTime_us() override;
+    uint64_t getSampleDuration_us() override;
 };
 
 #endif /* fileparser_hpp */

+ 6 - 3
examples/streamer/helpers.hpp

@@ -25,9 +25,9 @@
 
 struct ClientTrackData {
     std::shared_ptr<rtc::Track> track;
-	std::shared_ptr<rtc::RtcpSrReporter> sender;
+    std::shared_ptr<rtc::RtcpSrReporter> sender;
 
-	ClientTrackData(std::shared_ptr<rtc::Track> track, std::shared_ptr<rtc::RtcpSrReporter> sender);
+    ClientTrackData(std::shared_ptr<rtc::Track> track, std::shared_ptr<rtc::RtcpSrReporter> sender);
 };
 
 struct Client {
@@ -43,10 +43,13 @@ struct Client {
     }
     std::optional<std::shared_ptr<ClientTrackData>> video;
     std::optional<std::shared_ptr<ClientTrackData>> audio;
-    std::optional<std::shared_ptr<rtc::DataChannel>> dataChannel{};
+    std::optional<std::shared_ptr<rtc::DataChannel>> dataChannel;
+
     void setState(State state);
     State getState();
 
+    uint32_t rtpStartTimestamp = 0;
+
 private:
     std::shared_mutex _mutex;
     State state = State::Waiting;

+ 4 - 17
examples/streamer/main.cpp

@@ -364,17 +364,17 @@ shared_ptr<Stream> createStream(const string h264Samples, const unsigned fps, co
             for (auto clientTrack: tracks) {
                 auto client = clientTrack.id;
                 auto trackData = clientTrack.trackData;
+                auto rtpConfig = trackData->sender->rtpConfig;
+
                 // sample time is in us, we need to convert it to seconds
                 auto elapsedSeconds = double(sampleTime) / (1000 * 1000);
-                auto rtpConfig = trackData->sender->rtpConfig;
                 // get elapsed time in clock rate
                 uint32_t elapsedTimestamp = rtpConfig->secondsToTimestamp(elapsedSeconds);
-
                 // set new timestamp
                 rtpConfig->timestamp = rtpConfig->startTimestamp + elapsedTimestamp;
 
                 // get elapsed time in clock rate from last RTCP sender report
-                auto reportElapsedTimestamp = rtpConfig->timestamp - trackData->sender->previousReportedTimestamp;
+                auto reportElapsedTimestamp = rtpConfig->timestamp - trackData->sender->lastReportedTimestamp();
                 // check if last report was at least 1 second ago
                 if (rtpConfig->timestampToSeconds(reportElapsedTimestamp) > 1) {
                     trackData->sender->setNeedsToReport();
@@ -426,7 +426,7 @@ void sendInitialNalus(shared_ptr<Stream> stream, shared_ptr<ClientTrackData> vid
 
     // send previous NALU key frame so users don't have to wait to see stream works
     if (!initialNalus.empty()) {
-        const double frameDuration_s = double(h264->sampleDuration_us) / (1000 * 1000);
+        const double frameDuration_s = double(h264->getSampleDuration_us()) / (1000 * 1000);
         const uint32_t frameTimestampDuration = video->sender->rtpConfig->secondsToTimestamp(frameDuration_s);
         video->sender->rtpConfig->timestamp = video->sender->rtpConfig->startTimestamp - frameTimestampDuration * 2;
         video->track->send(initialNalus);
@@ -447,20 +447,7 @@ void addToStream(shared_ptr<Client> client, bool isAddingVideo) {
 
         // Audio and video tracks are collected now
         assert(client->video.has_value() && client->audio.has_value());
-
         auto video = client->video.value();
-        auto audio = client->audio.value();
-
-        auto currentTime_us = double(currentTimeInMicroSeconds());
-        auto currentTime_s = currentTime_us / (1000 * 1000);
-
-        // set start time of stream
-        video->sender->rtpConfig->setStartTime(currentTime_s, RtpPacketizationConfig::EpochStart::T1970);
-        audio->sender->rtpConfig->setStartTime(currentTime_s, RtpPacketizationConfig::EpochStart::T1970);
-
-        // start stat recording of RTCP SR
-        video->sender->startRecording();
-        audio->sender->startRecording();
 
         if (avStream.has_value()) {
             sendInitialNalus(avStream.value(), video);

+ 2 - 10
examples/streamer/stream.cpp

@@ -39,16 +39,8 @@ void usleep(__int64 usec)
 #include <unistd.h>
 #endif
 
-void StreamSource::stop() {
-    sampleTime_us = 0;
-    sample = {};
-}
-
-StreamSource::~StreamSource() {
-    stop();
-}
-
-Stream::Stream(std::shared_ptr<StreamSource> video, std::shared_ptr<StreamSource> audio): std::enable_shared_from_this<Stream>(), video(video), audio(audio) { }
+Stream::Stream(std::shared_ptr<StreamSource> video, std::shared_ptr<StreamSource> audio):
+	std::enable_shared_from_this<Stream>(), video(video), audio(audio) { }
 
 Stream::~Stream() {
     stop();

+ 7 - 9
examples/streamer/stream.hpp

@@ -24,19 +24,15 @@
 
 class StreamSource {
 protected:
-    uint64_t sampleTime_us = 0;
-    rtc::binary sample = {};
 
 public:
-    StreamSource() { }
     virtual void start() = 0;
-    virtual void stop();
+    virtual void stop() = 0;
     virtual void loadNextSample() = 0;
 
-    inline uint64_t getSampleTime_us() { return sampleTime_us; }
-    inline rtc::binary getSample() { return sample; }
-
-    ~StreamSource();
+    virtual uint64_t getSampleTime_us() = 0;
+    virtual uint64_t getSampleDuration_us() = 0;
+	virtual rtc::binary getSample() = 0;
 };
 
 class Stream: std::enable_shared_from_this<Stream> {
@@ -48,12 +44,14 @@ class Stream: std::enable_shared_from_this<Stream> {
 public:
     const std::shared_ptr<StreamSource> audio;
     const std::shared_ptr<StreamSource> video;
+
     Stream(std::shared_ptr<StreamSource> video, std::shared_ptr<StreamSource> audio);
+    ~Stream();
+
     enum class StreamSourceType {
         Audio,
         Video
     };
-    ~Stream();
 
 private:
     rtc::synchronized_callback<StreamSourceType, uint64_t, rtc::binary> sampleHandler;