diff --git a/README.md b/README.md index 82a85a2035..c348ffb6ed 100755 --- a/README.md +++ b/README.md @@ -155,6 +155,7 @@ For previous versions, please read: ## V4 changes +* v4.0, 2020-11-12, For [#1998][bug #1998], Support Firefox, use PT in offer. 4.0.55 * v4.0, 2020-11-11, For [#1508][bug #1508], Transform http header name to upper camel case. 4.0.54 * v4.0, 2020-11-06, For [#1657][bug #1657], Read cached data first in SSL. 4.0.48 * v4.0, 2020-11-06, For [#1657][bug #1657-3], support HTTPS Streaming(HTTPS-FLV, etc). 4.0.47 @@ -1791,6 +1792,7 @@ Winlin [bug #1657-1]: https://github.com/ossrs/srs/issues/1657#issuecomment-720889906 [bug #1657-2]: https://github.com/ossrs/srs/issues/1657#issuecomment-722904004 [bug #1657-3]: https://github.com/ossrs/srs/issues/1657#issuecomment-722971676 +[bug #1998]: https://github.com/ossrs/srs/issues/1998 [bug #zzzzzzzzzzzzz]: https://github.com/ossrs/srs/issues/zzzzzzzzzzzzz [exo #828]: https://github.com/google/ExoPlayer/pull/828 diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 364d4b6c22..5dd1806f94 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -646,6 +646,10 @@ srs_error_t SrsRtcPlayStream::send_packets(SrsRtcStream* source, const vectoris_audio()) { // TODO: FIXME: Any simple solution? SrsRtcAudioSendTrack* audio_track = audio_tracks_[pkt->header.get_ssrc()]; + + // The player may change the PT, so it's not equal to publisher's. + pkt->header.set_payload_type(audio_track->get_track_media_pt()); + if ((err = audio_track->on_rtp(pkt, info)) != srs_success) { return srs_error_wrap(err, "audio track, SSRC=%u, SEQ=%u", pkt->header.get_ssrc(), pkt->header.get_sequence()); } @@ -654,6 +658,10 @@ srs_error_t SrsRtcPlayStream::send_packets(SrsRtcStream* source, const vectorheader.get_ssrc()]; + + // The player may change the PT, so it's not equal to publisher's. + pkt->header.set_payload_type(video_track->get_track_media_pt()); + if ((err = video_track->on_rtp(pkt, info)) != srs_success) { return srs_error_wrap(err, "video track, SSRC=%u, SEQ=%u", pkt->header.get_ssrc(), pkt->header.get_sequence()); } @@ -2580,11 +2588,30 @@ srs_error_t SrsRtcConnection::on_binding_request(SrsStunPacket* r) return err; } -// For example, 42001f 42e01f, see https://blog.csdn.net/epubcn/article/details/102802108 -bool srs_sdp_has_h264_profile(const SrsSdp& sdp, const string& profile) +bool srs_sdp_has_h264_profile(const SrsMediaPayloadType& payload_type, const string& profile) { srs_error_t err = srs_success; + if (payload_type.format_specific_param_.empty()) { + return false; + } + + H264SpecificParam h264_param; + if ((err = srs_parse_h264_fmtp(payload_type.format_specific_param_, h264_param)) != srs_success) { + srs_error_reset(err); + return false; + } + + if (h264_param.profile_level_id == profile) { + return true; + } + + return false; +} + +// For example, 42001f 42e01f, see https://blog.csdn.net/epubcn/article/details/102802108 +bool srs_sdp_has_h264_profile(const SrsSdp& sdp, const string& profile) +{ for (size_t i = 0; i < sdp.media_descs_.size(); ++i) { const SrsMediaDesc& desc = sdp.media_descs_[i]; if (!desc.is_video()) { @@ -2598,17 +2625,7 @@ bool srs_sdp_has_h264_profile(const SrsSdp& sdp, const string& profile) for (std::vector::iterator it = payloads.begin(); it != payloads.end(); ++it) { const SrsMediaPayloadType& payload_type = *it; - - if (payload_type.format_specific_param_.empty()) { - continue; - } - - H264SpecificParam h264_param; - if ((err = srs_parse_h264_fmtp(payload_type.format_specific_param_, h264_param)) != srs_success) { - srs_error_reset(err); continue; - } - - if (h264_param.profile_level_id == profile) { + if (srs_sdp_has_h264_profile(payload_type, profile)) { return true; } } @@ -2917,6 +2934,7 @@ srs_error_t SrsRtcConnection::negotiate_play_capability(SrsRequest* req, const S bool nack_enabled = _srs_config->get_rtc_nack_enabled(req->vhost); bool twcc_enabled = _srs_config->get_rtc_twcc_enabled(req->vhost); + bool has_42e01f = srs_sdp_has_h264_profile(remote_sdp, "42e01f"); SrsRtcStream* source = NULL; if ((err = _srs_rtc_sources->fetch_or_create(req, &source)) != srs_success) { @@ -2925,6 +2943,7 @@ srs_error_t SrsRtcConnection::negotiate_play_capability(SrsRequest* req, const S for (size_t i = 0; i < remote_sdp.media_descs_.size(); ++i) { const SrsMediaDesc& remote_media_desc = remote_sdp.media_descs_[i]; + // Whether feature enabled in remote extmap. int remote_twcc_id = 0; if (true) { @@ -2938,33 +2957,41 @@ srs_error_t SrsRtcConnection::negotiate_play_capability(SrsRequest* req, const S } std::vector track_descs; - std::vector remote_rtcp_fb; + SrsMediaPayloadType* remote_payload = NULL; if (remote_media_desc.is_audio()) { // TODO: check opus format specific param - std::vector payloads = remote_media_desc.find_media_with_encoding_name("opus"); + vector payloads = remote_media_desc.find_media_with_encoding_name("opus"); if (payloads.empty()) { return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no valid found opus payload type"); } - SrsMediaPayloadType payload = payloads.at(0); - remote_rtcp_fb = payload.rtcp_fb_; - + remote_payload = &payloads.at(0); track_descs = source->get_track_desc("audio", "opus"); } else if (remote_media_desc.is_video()) { // TODO: check opus format specific param - std::vector payloads = remote_media_desc.find_media_with_encoding_name("H264"); + vector payloads = remote_media_desc.find_media_with_encoding_name("H264"); if (payloads.empty()) { return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no valid found h264 payload type"); } - SrsMediaPayloadType payload = payloads.at(0); - remote_rtcp_fb = payload.rtcp_fb_; + for (int j = 0; j < (int)payloads.size(); j++) { + SrsMediaPayloadType& payload = payloads.at(j); + // If exists 42e01f profile, choose it; otherwise, use the first payload. + if (!has_42e01f || srs_sdp_has_h264_profile(payload, "42e01f")) { + remote_payload = &payloads.at(j); + break; + } + } track_descs = source->get_track_desc("video", "H264"); } for (int i = 0; i < (int)track_descs.size(); ++i) { SrsRtcTrackDescription* track = track_descs[i]->copy(); + + // Use remote/source/offer PayloadType. + track->media_->pt_ = remote_payload->payload_type_; + track->mid_ = remote_media_desc.mid_; uint32_t publish_ssrc = track->ssrc_; diff --git a/trunk/src/app/srs_app_rtc_source.cpp b/trunk/src/app/srs_app_rtc_source.cpp index 65a10b26f7..adf54960c0 100644 --- a/trunk/src/app/srs_app_rtc_source.cpp +++ b/trunk/src/app/srs_app_rtc_source.cpp @@ -1941,6 +1941,11 @@ std::string SrsRtcSendTrack::get_track_id() return track_desc_->id_; } +int SrsRtcSendTrack::get_track_media_pt() +{ + return track_desc_->media_->pt_; +} + void SrsRtcSendTrack::on_recv_nack() { SrsRtcTrackStatistic* statistic = statistic_; diff --git a/trunk/src/app/srs_app_rtc_source.hpp b/trunk/src/app/srs_app_rtc_source.hpp index 6eaf89c2b8..57736cdeb7 100644 --- a/trunk/src/app/srs_app_rtc_source.hpp +++ b/trunk/src/app/srs_app_rtc_source.hpp @@ -426,9 +426,6 @@ class SrsRtcTrackDescription int get_rtp_extension_id(std::string uri); public: SrsRtcTrackDescription* copy(); -public: - // find media with payload type. - SrsMediaPayloadType generate_media_payload_type(int payload_type); }; class SrsRtcStreamDescription @@ -565,6 +562,7 @@ class SrsRtcSendTrack bool set_track_status(bool active); bool get_track_status(); std::string get_track_id(); + int get_track_media_pt(); public: virtual srs_error_t on_rtp(SrsRtpPacket2* pkt, SrsRtcPlayStreamStatistic& info) = 0; virtual srs_error_t on_rtcp(SrsRtpPacket2* pkt) = 0; diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index b1c174c72e..c6c5056234 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -24,6 +24,6 @@ #ifndef SRS_CORE_VERSION4_HPP #define SRS_CORE_VERSION4_HPP -#define SRS_VERSION4_REVISION 54 +#define SRS_VERSION4_REVISION 55 #endif