diff --git a/webrtc/Sdp.cpp b/webrtc/Sdp.cpp index f83b2b7e..91d822bf 100644 --- a/webrtc/Sdp.cpp +++ b/webrtc/Sdp.cpp @@ -1331,6 +1331,10 @@ void RtcConfigure::matchMedia(shared_ptr &ret, TrackType type, const if (!configure.enable) { return; } + bool failed = false; + +RETRY: + for (auto &codec : configure.preferred_codec) { for (auto &offer_media : medias) { if (offer_media.type != type) { @@ -1342,12 +1346,15 @@ void RtcConfigure::matchMedia(shared_ptr &ret, TrackType type, const } const RtcCodecPlan *offer_plan_ptr = nullptr; for (auto &plan : offer_media.plan) { - if (getCodecId(plan.codec) != codec) { - continue; - } - //命中偏好的编码格式 - if (!onMatchCodecPlan(plan, codec)) { - continue; + if (!failed) { + //如果匹配失败了,那么随便选择一个plan + if (getCodecId(plan.codec) != codec) { + continue; + } + //命中偏好的编码格式 + if (!onMatchCodecPlan(plan, codec)) { + continue; + } } //找到中意的codec offer_plan_ptr = &plan; @@ -1476,4 +1483,32 @@ void RtcConfigure::matchMedia(shared_ptr &ret, TrackType type, const return; } } + + if (!failed) { + //只重试一次 + failed = true; + goto RETRY; + } +} + +void RtcConfigure::setPlayRtspInfo(const string &sdp){ + RtcSession session; + session.loadFrom(sdp, false); + for (auto &m : session.media) { + switch (m.type) { + case TrackVideo : _rtsp_video_plan = std::make_shared(m.plan[0]); break; + case TrackAudio : _rtsp_audio_plan = std::make_shared(m.plan[0]); break; + default: break; + } + } +} + +bool RtcConfigure::onMatchCodecPlan(const RtcCodecPlan &plan, CodecId codec){ + if (_rtsp_audio_plan && codec == getCodecId(_rtsp_audio_plan->codec)) { + if (plan.sample_rate != _rtsp_audio_plan->sample_rate || plan.channel != _rtsp_audio_plan->channel) { + //音频采样率和通道数必须相同 + return false; + } + } + return true; } diff --git a/webrtc/Sdp.h b/webrtc/Sdp.h index 0d0f972a..e7ba518e 100644 --- a/webrtc/Sdp.h +++ b/webrtc/Sdp.h @@ -574,6 +574,7 @@ public: //rtc传输编码方案 class RtcCodecPlan{ public: + using Ptr = shared_ptr; uint8_t pt; string codec; uint32_t sample_rate; @@ -702,9 +703,15 @@ public: shared_ptr createAnswer(const RtcSession &offer); + void setPlayRtspInfo(const string &sdp); + private: void matchMedia(shared_ptr &ret, TrackType type, const vector &medias, const RtcTrackConfigure &configure); - bool onMatchCodecPlan(const RtcCodecPlan &plan, CodecId codec) { return true; } + bool onMatchCodecPlan(const RtcCodecPlan &plan, CodecId codec); + +private: + RtcCodecPlan::Ptr _rtsp_video_plan; + RtcCodecPlan::Ptr _rtsp_audio_plan; }; diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index 0e32859b..7aa6417b 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -324,16 +324,19 @@ void WebRtcTransportImp::onRtcConfigure(RtcConfigure &configure) const { //这是播放 configure.video.direction = RtpDirection::sendonly; configure.audio.direction = RtpDirection::sendonly; + configure.setPlayRtspInfo(_src->getSdp()); _rtsp_send_sdp.loadFrom(_src->getSdp(), false); //根据rtsp流的相关信息,设置rtc最佳编码 for (auto &m : _rtsp_send_sdp.media) { switch (m.type) { case TrackVideo: { - configure.video.preferred_codec.insert(configure.video.preferred_codec.begin(), getCodecId(m.plan[0].codec)); + configure.video.preferred_codec.clear(); + configure.video.preferred_codec.emplace_back(getCodecId(m.plan[0].codec)); break; } case TrackAudio: { - configure.audio.preferred_codec.insert(configure.audio.preferred_codec.begin(),getCodecId(m.plan[0].codec)); + configure.audio.preferred_codec.clear(); + configure.audio.preferred_codec.emplace_back(getCodecId(m.plan[0].codec)); break; } default: