diff --git a/src/Rtp/PSEncoder.cpp b/src/Rtp/PSEncoder.cpp index 4e5c31d5..66e39bc7 100644 --- a/src/Rtp/PSEncoder.cpp +++ b/src/Rtp/PSEncoder.cpp @@ -22,7 +22,7 @@ namespace mediakit{ PSEncoderImp::PSEncoderImp(uint32_t ssrc, uint8_t payload_type) : MpegMuxer(true) { GET_CONFIG(uint32_t,video_mtu,Rtp::kVideoMtuSize); _rtp_encoder = std::make_shared(); - _rtp_encoder->setRtpInfo(ssrc, video_mtu, 90000, payload_type, 0); + _rtp_encoder->setRtpInfo(ssrc, video_mtu, 90000, payload_type); auto ring = std::make_shared(); ring->setDelegate(std::make_shared([this](RtpPacket::Ptr rtp, bool is_key) { onRTP(std::move(rtp), is_key); })); _rtp_encoder->setRtpRing(std::move(ring)); diff --git a/src/Rtp/RawEncoder.cpp b/src/Rtp/RawEncoder.cpp index b680eccb..4bc17af7 100644 --- a/src/Rtp/RawEncoder.cpp +++ b/src/Rtp/RawEncoder.cpp @@ -72,7 +72,7 @@ RtpCodec::Ptr RawEncoderImp::createRtpEncoder(const Track::Ptr &track) { sample_rate = std::static_pointer_cast(track)->getAudioSampleRate(); } auto ret = Factory::getRtpEncoderByCodecId(track->getCodecId(), _payload_type); - ret->setRtpInfo(_ssrc, mtu, sample_rate, _payload_type, 2 * track->getTrackType()); + ret->setRtpInfo(_ssrc, mtu, sample_rate, _payload_type); return ret; } diff --git a/src/Rtsp/RtpCodec.cpp b/src/Rtsp/RtpCodec.cpp index 83db75fe..65ee311f 100644 --- a/src/Rtsp/RtpCodec.cpp +++ b/src/Rtsp/RtpCodec.cpp @@ -19,6 +19,7 @@ RtpPacket::Ptr RtpInfo::makeRtp(TrackType type, const void* data, size_t len, bo rtp->setSize(payload_len + RtpPacket::kRtpTcpHeaderSize); rtp->sample_rate = _sample_rate; rtp->type = type; + rtp->track_index = _track_index; //rtsp over tcp 头 auto ptr = (uint8_t *) rtp->data(); diff --git a/src/Rtsp/RtpCodec.h b/src/Rtsp/RtpCodec.h index 0d1c7a80..d63f1962 100644 --- a/src/Rtsp/RtpCodec.h +++ b/src/Rtsp/RtpCodec.h @@ -54,7 +54,7 @@ class RtpInfo { public: using Ptr = std::shared_ptr; - RtpInfo(uint32_t ssrc, size_t mtu_size, uint32_t sample_rate, uint8_t pt, uint8_t interleaved) { + RtpInfo(uint32_t ssrc, size_t mtu_size, uint32_t sample_rate, uint8_t pt, uint8_t interleaved, int track_index) { if (ssrc == 0) { ssrc = ((uint64_t) this) & 0xFFFFFFFF; } @@ -63,6 +63,7 @@ public: _mtu_size = mtu_size; _sample_rate = sample_rate; _interleaved = interleaved; + _track_index = track_index; } //返回rtp负载最大长度 @@ -78,6 +79,7 @@ private: uint16_t _seq = 0; uint32_t _ssrc; uint32_t _sample_rate; + int _track_index; size_t _mtu_size; }; @@ -85,8 +87,8 @@ class RtpCodec : public RtpRing, public FrameDispatcher { public: using Ptr = std::shared_ptr; - void setRtpInfo(uint32_t ssrc, size_t mtu_size, uint32_t sample_rate, uint8_t pt, uint8_t interleaved) { - _rtp_info.reset(new RtpInfo(ssrc, mtu_size, sample_rate, pt, interleaved)); + void setRtpInfo(uint32_t ssrc, size_t mtu_size, uint32_t sample_rate, uint8_t pt, uint8_t interleaved = 0, int track_index = 0) { + _rtp_info.reset(new RtpInfo(ssrc, mtu_size, sample_rate, pt, interleaved, track_index)); } RtpInfo &getRtpInfo() { return *_rtp_info; } diff --git a/src/Rtsp/Rtsp.h b/src/Rtsp/Rtsp.h index 8963c8ce..fde5caea 100644 --- a/src/Rtsp/Rtsp.h +++ b/src/Rtsp/Rtsp.h @@ -166,7 +166,7 @@ public: // ntp时间戳 uint64_t ntp_stamp; - bool disable_ntp = false; + int track_index; static Ptr create(); diff --git a/src/Rtsp/RtspMuxer.cpp b/src/Rtsp/RtspMuxer.cpp index f2967c04..dae5f111 100644 --- a/src/Rtsp/RtspMuxer.cpp +++ b/src/Rtsp/RtspMuxer.cpp @@ -19,18 +19,19 @@ namespace mediakit { void RtspMuxer::onRtp(RtpPacket::Ptr in, bool is_key) { if (_live) { - if (_rtp_stamp[in->type] != in->getHeader()->stamp) { + auto &ref = _tracks[in->track_index]; + if (ref.rtp_stamp != in->getHeader()->stamp) { // rtp时间戳变化才计算ntp,节省cpu资源 int64_t stamp_ms = in->getStamp() * uint64_t(1000) / in->sample_rate; int64_t stamp_ms_inc; // 求rtp时间戳增量 - _stamp[in->type].revise(stamp_ms, stamp_ms, stamp_ms_inc, stamp_ms_inc); - _rtp_stamp[in->type] = in->getHeader()->stamp; - _ntp_stamp[in->type] = stamp_ms_inc + _ntp_stamp_start; + ref.stamp.revise(stamp_ms, stamp_ms, stamp_ms_inc, stamp_ms_inc); + ref.rtp_stamp = in->getHeader()->stamp; + ref.ntp_stamp = stamp_ms_inc + _ntp_stamp_start; } // rtp拦截入口,此处统一赋值ntp - in->ntp_stamp = _ntp_stamp[in->type]; + in->ntp_stamp = ref.ntp_stamp; } else { // 点播情况下设置ntp时间戳为rtp时间戳加基准ntp时间戳 in->ntp_stamp = _ntp_stamp_start + (in->getStamp() * uint64_t(1000) / in->sample_rate); @@ -55,16 +56,20 @@ RtspMuxer::RtspMuxer(const TitleSdp::Ptr &title) { } bool RtspMuxer::addTrack(const Track::Ptr &track) { - auto &encoder = _encoder[track->getTrackType()]; - if (encoder) { - WarnL << "Already add a track kind of: " << track->getTrackTypeStr() - << ", ignore track: " << track->getCodecName(); + if (_track_existed[track->getTrackType()]) { + // rtsp不支持多个同类型track + WarnL << "Already add a track kind of: " << track->getTrackTypeStr() << ", ignore track: " << track->getCodecName(); return false; } + + auto &ref = _tracks[track->getIndex()]; + auto &encoder = ref.encoder; + CHECK(!encoder); + // payload type 96以后则为动态pt Sdp::Ptr sdp = track->getSdp(96 + _index); if (!sdp) { - WarnL << "rtsp复用器不支持该编码:" << track->getCodecName(); + WarnL << "Unsupported codec: " << track->getCodecName(); return false; } @@ -73,6 +78,9 @@ bool RtspMuxer::addTrack(const Track::Ptr &track) { return false; } + // 标记已经存在该类型track + _track_existed[track->getTrackType()] = true; + { static atomic s_ssrc(0); uint32_t ssrc = s_ssrc++; @@ -90,7 +98,7 @@ bool RtspMuxer::addTrack(const Track::Ptr &track) { GET_CONFIG(uint32_t, audio_mtu, Rtp::kAudioMtuSize); GET_CONFIG(uint32_t, video_mtu, Rtp::kVideoMtuSize); auto mtu = track->getTrackType() == TrackVideo ? video_mtu : audio_mtu; - encoder->setRtpInfo(ssrc, mtu, sdp->getSampleRate(), sdp->getPayloadType(), 2 * track->getTrackType()); + encoder->setRtpInfo(ssrc, mtu, sdp->getSampleRate(), sdp->getPayloadType(), 2 * track->getTrackType(), track->getIndex()); } // 设置rtp输出环形缓存 @@ -106,28 +114,33 @@ bool RtspMuxer::addTrack(const Track::Ptr &track) { trySyncTrack(); // rtp的时间戳是pts,允许回退 - _stamp[TrackVideo].enableRollback(true); - + if (track->getTrackType() == TrackVideo) { + ref.stamp.enableRollback(true); + } ++_index; return true; } void RtspMuxer::trySyncTrack() { - if (_encoder[TrackAudio] && _encoder[TrackVideo]) { - // 音频时间戳同步于视频,因为音频时间戳被修改后不影响播放 - _stamp[TrackAudio].syncTo(_stamp[TrackVideo]); + Stamp *first = nullptr; + for (auto &pr : _tracks) { + if (!first) { + first = &pr.second.stamp; + } else { + pr.second.stamp.syncTo(*first); + } } } bool RtspMuxer::inputFrame(const Frame::Ptr &frame) { - auto &encoder = _encoder[frame->getTrackType()]; + auto &encoder = _tracks[frame->getIndex()].encoder; return encoder ? encoder->inputFrame(frame) : false; } void RtspMuxer::flush() { - for (auto &encoder : _encoder) { - if (encoder) { - encoder->flush(); + for (auto &pr : _tracks) { + if (pr.second.encoder) { + pr.second.encoder->flush(); } } } @@ -142,9 +155,8 @@ RtpRing::RingType::Ptr RtspMuxer::getRtpRing() const { void RtspMuxer::resetTracks() { _sdp.clear(); - for (auto &encoder : _encoder) { - encoder = nullptr; - } + _tracks.clear(); + CLEAR_ARR(_track_existed); } } /* namespace mediakit */ \ No newline at end of file diff --git a/src/Rtsp/RtspMuxer.h b/src/Rtsp/RtspMuxer.h index ba528ecf..00f356e0 100644 --- a/src/Rtsp/RtspMuxer.h +++ b/src/Rtsp/RtspMuxer.h @@ -85,13 +85,20 @@ private: private: bool _live = true; + bool _track_existed[2] = { false, false }; + uint8_t _index {0}; - uint32_t _rtp_stamp[TrackMax]{0}; - uint64_t _ntp_stamp[TrackMax]{0}; uint64_t _ntp_stamp_start; std::string _sdp; - Stamp _stamp[TrackMax]; - RtpCodec::Ptr _encoder[TrackMax]; + + struct TrackInfo { + Stamp stamp; + uint32_t rtp_stamp { 0 }; + uint64_t ntp_stamp { 0 }; + RtpCodec::Ptr encoder; + }; + + std::unordered_map _tracks; RtpRing::RingType::Ptr _rtpRing; RtpRing::RingType::Ptr _rtpInterceptor; };