diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index a6646304e..c36729d4b 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -2560,6 +2560,43 @@ 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) +{ + srs_error_t err = srs_success; + + for (size_t i = 0; i < sdp.media_descs_.size(); ++i) { + const SrsMediaDesc& desc = sdp.media_descs_[i]; + if (!desc.is_video()) { + continue; + } + + std::vector payloads = desc.find_media_with_encoding_name("H264"); + if (payloads.empty()) { + continue; + } + + 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) { + return true; + } + } + } + + return false; +} + srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRequest* req, const SrsSdp& remote_sdp, SrsRtcStreamDescription* stream_desc) { srs_error_t err = srs_success; @@ -2570,6 +2607,7 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRequest* req, cons 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"); for (size_t i = 0; i < remote_sdp.media_descs_.size(); ++i) { const SrsMediaDesc& remote_media_desc = remote_sdp.media_descs_[i]; @@ -2641,8 +2679,11 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRequest* req, cons srs_error_reset(err); continue; } + // If not exists 42e01f, we pick up any profile such as 42001f. + bool profile_matched = (!has_42e01f || h264_param.profile_level_id == "42e01f"); + // Try to pick the "best match" H.264 payload type. - if (h264_param.packetization_mode == "1" && h264_param.level_asymmerty_allow == "1") { + if (h264_param.packetization_mode == "1" && h264_param.level_asymmerty_allow == "1" && profile_matched) { // if the playload is opus, and the encoding_param_ is channel SrsVideoPayload* video_payload = new SrsVideoPayload(iter->payload_type_, iter->encoding_name_, iter->clock_rate_); video_payload->set_h264_param_desc(iter->format_specific_param_);