From 14da5ab2d8ab9fb739b3aaf2894066af58c5b583 Mon Sep 17 00:00:00 2001 From: xiongguangjie Date: Sat, 9 Jul 2022 22:30:43 +0800 Subject: [PATCH] when start send rtp wait key rtp previous drop (#1789) --- src/Extension/CommonRtp.cpp | 5 +++-- src/Extension/Frame.h | 10 ++++++---- src/Rtp/PSEncoder.cpp | 4 ++-- src/Rtp/PSEncoder.h | 2 +- src/Rtp/RawEncoder.cpp | 4 ++-- src/Rtp/RawEncoder.h | 3 +-- src/Rtp/RtpCache.cpp | 26 +++++++++++++++++++------- src/Rtp/RtpCache.h | 8 +++++--- 8 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/Extension/CommonRtp.cpp b/src/Extension/CommonRtp.cpp index ff7def3c..9ba9b682 100644 --- a/src/Extension/CommonRtp.cpp +++ b/src/Extension/CommonRtp.cpp @@ -76,7 +76,7 @@ bool CommonRtpEncoder::inputFrame(const Frame::Ptr &frame){ auto len = frame->size() - frame->prefixSize(); auto remain_size = len; auto max_size = getMaxSize(); - + bool is_key = frame->keyFrame(); bool mark = false; while (remain_size > 0) { size_t rtp_size; @@ -86,9 +86,10 @@ bool CommonRtpEncoder::inputFrame(const Frame::Ptr &frame){ rtp_size = remain_size; mark = true; } - RtpCodec::inputRtp(makeRtp(getTrackType(), ptr, rtp_size, mark, stamp), false); + RtpCodec::inputRtp(makeRtp(getTrackType(), ptr, rtp_size, mark, stamp), is_key); ptr += rtp_size; remain_size -= rtp_size; + is_key = false; } return len > 0; } \ No newline at end of file diff --git a/src/Extension/Frame.h b/src/Extension/Frame.h index 497eb0c5..6f353088 100644 --- a/src/Extension/Frame.h +++ b/src/Extension/Frame.h @@ -391,17 +391,18 @@ class FrameFromPtr : public Frame{ public: typedef std::shared_ptr Ptr; - FrameFromPtr(CodecId codec_id, char *ptr, size_t size, uint32_t dts, uint32_t pts = 0, size_t prefix_size = 0) - : FrameFromPtr(ptr, size, dts, pts, prefix_size) { + FrameFromPtr(CodecId codec_id, char *ptr, size_t size, uint32_t dts, uint32_t pts = 0, size_t prefix_size = 0,bool is_key = false ) + : FrameFromPtr(ptr, size, dts, pts, prefix_size,is_key) { _codec_id = codec_id; } - FrameFromPtr(char *ptr, size_t size, uint32_t dts, uint32_t pts = 0, size_t prefix_size = 0){ + FrameFromPtr(char *ptr, size_t size, uint32_t dts, uint32_t pts = 0, size_t prefix_size = 0,bool is_key = false){ _ptr = ptr; _size = size; _dts = dts; _pts = pts; _prefix_size = prefix_size; + _is_key = is_key; } char *data() const override{ @@ -440,7 +441,7 @@ public: } bool keyFrame() const override { - return false; + return _is_key; } bool configFrame() const override{ @@ -457,6 +458,7 @@ protected: size_t _size; size_t _prefix_size; CodecId _codec_id = CodecInvalid; + bool _is_key; }; /** diff --git a/src/Rtp/PSEncoder.cpp b/src/Rtp/PSEncoder.cpp index 71ab3171..aaff629f 100644 --- a/src/Rtp/PSEncoder.cpp +++ b/src/Rtp/PSEncoder.cpp @@ -23,7 +23,7 @@ PSEncoderImp::PSEncoderImp(uint32_t ssrc, uint8_t payload_type) : MpegMuxer(true _rtp_encoder = std::make_shared(CodecInvalid, ssrc, video_mtu, 90000, payload_type, 0); _rtp_encoder->setRtpRing(std::make_shared()); _rtp_encoder->getRtpRing()->setDelegate(std::make_shared([this](RtpPacket::Ptr rtp, bool is_key){ - onRTP(std::move(rtp)); + onRTP(std::move(rtp),is_key); })); InfoL << this << " " << printSSRC(_rtp_encoder->getSsrc()); } @@ -36,7 +36,7 @@ void PSEncoderImp::onWrite(std::shared_ptr buffer, uint32_t stamp, bool if (!buffer) { return; } - _rtp_encoder->inputFrame(std::make_shared(buffer->data(), buffer->size(), stamp, stamp)); + _rtp_encoder->inputFrame(std::make_shared(buffer->data(), buffer->size(), stamp, stamp,0,key_pos)); } }//namespace mediakit diff --git a/src/Rtp/PSEncoder.h b/src/Rtp/PSEncoder.h index 76e7418f..adbf76f7 100644 --- a/src/Rtp/PSEncoder.h +++ b/src/Rtp/PSEncoder.h @@ -27,7 +27,7 @@ public: protected: //rtp打包后回调 - virtual void onRTP(toolkit::Buffer::Ptr rtp) = 0; + virtual void onRTP(toolkit::Buffer::Ptr rtp,bool is_key = false) = 0; protected: void onWrite(std::shared_ptr buffer, uint32_t stamp, bool key_pos) override; diff --git a/src/Rtp/RawEncoder.cpp b/src/Rtp/RawEncoder.cpp index 714350b6..f97b5b38 100644 --- a/src/Rtp/RawEncoder.cpp +++ b/src/Rtp/RawEncoder.cpp @@ -35,7 +35,7 @@ bool RawEncoderImp::addTrack(const Track::Ptr &track){ _rtp_encoder = createRtpEncoder(track); _rtp_encoder->setRtpRing(std::make_shared()); _rtp_encoder->getRtpRing()->setDelegate(std::make_shared([this](RtpPacket::Ptr rtp, bool is_key){ - onRTP(std::move(rtp)); + onRTP(std::move(rtp),true); })); return true; } @@ -44,7 +44,7 @@ bool RawEncoderImp::addTrack(const Track::Ptr &track){ _rtp_encoder = createRtpEncoder(track); _rtp_encoder->setRtpRing(std::make_shared()); _rtp_encoder->getRtpRing()->setDelegate(std::make_shared([this](RtpPacket::Ptr rtp, bool is_key){ - onRTP(std::move(rtp)); + onRTP(std::move(rtp),is_key); })); return true; } diff --git a/src/Rtp/RawEncoder.h b/src/Rtp/RawEncoder.h index 342e9e02..6a18f450 100644 --- a/src/Rtp/RawEncoder.h +++ b/src/Rtp/RawEncoder.h @@ -43,10 +43,9 @@ public: protected: //rtp打包后回调 - virtual void onRTP(toolkit::Buffer::Ptr rtp) = 0; + virtual void onRTP(toolkit::Buffer::Ptr rtp, bool is_key = false) = 0; private: RtpCodec::Ptr createRtpEncoder(const Track::Ptr &track); - uint32_t _ssrc; uint8_t _payload_type; bool _sendAudio; diff --git a/src/Rtp/RtpCache.cpp b/src/Rtp/RtpCache.cpp index 08ecba22..89b05d4a 100644 --- a/src/Rtp/RtpCache.cpp +++ b/src/Rtp/RtpCache.cpp @@ -19,25 +19,37 @@ namespace mediakit{ RtpCache::RtpCache(onFlushed cb) { _cb = std::move(cb); } - +bool RtpCache::firstKeyReady(bool in) { + if(_first_key){ + return _first_key; + } + _first_key = in; + return _first_key; +} void RtpCache::onFlush(std::shared_ptr > rtp_list, bool) { _cb(std::move(rtp_list)); } -void RtpCache::input(uint64_t stamp, Buffer::Ptr buffer) { - inputPacket(stamp, true, std::move(buffer), false); +void RtpCache::input(uint64_t stamp, Buffer::Ptr buffer,bool is_key ) { + inputPacket(stamp, true, std::move(buffer), is_key); } -void RtpCachePS::onRTP(Buffer::Ptr buffer) { +void RtpCachePS::onRTP(Buffer::Ptr buffer,bool is_key) { + if(!firstKeyReady(is_key)){ + return; + } auto rtp = std::static_pointer_cast(buffer); auto stamp = rtp->getStampMS(); - input(stamp, std::move(buffer)); + input(stamp, std::move(buffer),is_key); } -void RtpCacheRaw::onRTP(Buffer::Ptr buffer) { +void RtpCacheRaw::onRTP(Buffer::Ptr buffer,bool is_key) { + if(!firstKeyReady(is_key)){ + return; + } auto rtp = std::static_pointer_cast(buffer); auto stamp = rtp->getStampMS(); - input(stamp, std::move(buffer)); + input(stamp, std::move(buffer),is_key); } }//namespace mediakit diff --git a/src/Rtp/RtpCache.h b/src/Rtp/RtpCache.h index b393bca4..4144b345 100644 --- a/src/Rtp/RtpCache.h +++ b/src/Rtp/RtpCache.h @@ -30,13 +30,15 @@ protected: * 输入rtp(目的是为了合并写) * @param buffer rtp数据 */ - void input(uint64_t stamp, toolkit::Buffer::Ptr buffer); + void input(uint64_t stamp, toolkit::Buffer::Ptr buffer,bool is_key = false); + bool firstKeyReady(bool in); protected: void onFlush(std::shared_ptr > rtp_list, bool) override; private: onFlushed _cb; + bool _first_key = false; }; class RtpCachePS : public RtpCache, public PSEncoderImp{ @@ -45,7 +47,7 @@ public: ~RtpCachePS() override = default; protected: - void onRTP(toolkit::Buffer::Ptr rtp) override; + void onRTP(toolkit::Buffer::Ptr rtp,bool is_key = false) override; }; @@ -55,7 +57,7 @@ public: ~RtpCacheRaw() override = default; protected: - void onRTP(toolkit::Buffer::Ptr rtp) override; + void onRTP(toolkit::Buffer::Ptr rtp,bool is_key = false) override; }; }//namespace mediakit