From 523589dbd84729b5aba00a581d9111a515f50bce Mon Sep 17 00:00:00 2001 From: Magnus Jedvert Date: Thu, 23 Nov 2017 13:24:53 +0100 Subject: [PATCH] Create common helper method for comparing video formats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unfortunately, H264 makes it non-trivial to compare video formats for equality. For every video format besides H264 it's enough to look at the name, but for H264, we need to dig into the parameters. This logic is currently in several places, and this CL unifies it to one place. Bug: webrtc:7925 Change-Id: I83a516b108d6b4d6792fd0bf1d24296916d9f7fa Reviewed-on: https://webrtc-review.googlesource.com/25120 Commit-Queue: Magnus Jedvert Reviewed-by: Sami Kalliomäki Cr-Commit-Position: refs/heads/master@{#20853} --- media/base/codec.cc | 34 +++++++++---------- media/base/codec.h | 4 +++ media/base/h264_profile_level_id.cc | 11 ++++++ media/base/h264_profile_level_id.h | 5 +++ media/engine/convert_legacy_video_factory.cc | 22 ++---------- .../src/jni/hardwarevideoencoderfactory.cc | 15 ++------ 6 files changed, 41 insertions(+), 50 deletions(-) diff --git a/media/base/codec.cc b/media/base/codec.cc index 59c61fe69a..98e52d6848 100644 --- a/media/base/codec.cc +++ b/media/base/codec.cc @@ -21,17 +21,6 @@ namespace cricket { -static bool IsSameH264Profile(const CodecParameterMap& params1, - const CodecParameterMap& params2) { - const rtc::Optional profile_level_id = - webrtc::H264::ParseSdpProfileLevelId(params1); - const rtc::Optional other_profile_level_id = - webrtc::H264::ParseSdpProfileLevelId(params2); - // Compare H264 profiles, but not levels. - return profile_level_id && other_profile_level_id && - profile_level_id->profile == other_profile_level_id->profile; -} - FeedbackParams::FeedbackParams() = default; bool FeedbackParam::operator==(const FeedbackParam& other) const { @@ -259,7 +248,7 @@ bool VideoCodec::Matches(const VideoCodec& other) const { if (!Codec::Matches(other)) return false; if (CodecNamesEq(name.c_str(), kH264CodecName)) - return IsSameH264Profile(params, other.params); + return webrtc::H264::IsSameH264Profile(params, other.params); return true; } @@ -355,15 +344,24 @@ const VideoCodec* FindMatchingCodec( const std::vector& supported_codecs, const VideoCodec& codec) { for (const VideoCodec& supported_codec : supported_codecs) { - if (!CodecNamesEq(codec.name, supported_codec.name)) - continue; - if (CodecNamesEq(codec.name.c_str(), kH264CodecName) && - !IsSameH264Profile(codec.params, supported_codec.params)) { - continue; + if (IsSameCodec(codec.name, codec.params, supported_codec.name, + supported_codec.params)) { + return &supported_codec; } - return &supported_codec; } return nullptr; } +bool IsSameCodec(const std::string& name1, + const CodecParameterMap& params1, + const std::string& name2, + const CodecParameterMap& params2) { + // If different names (case insensitive), then not same formats. + if (!CodecNamesEq(name1, name2)) + return false; + // For every format besides H264, comparing names is enough. + return !CodecNamesEq(name1.c_str(), kH264CodecName) || + webrtc::H264::IsSameH264Profile(params1, params2); +} + } // namespace cricket diff --git a/media/base/codec.h b/media/base/codec.h index 6c88998077..6a2dcf4529 100644 --- a/media/base/codec.h +++ b/media/base/codec.h @@ -254,6 +254,10 @@ bool HasTransportCc(const Codec& codec); const VideoCodec* FindMatchingCodec( const std::vector& supported_codecs, const VideoCodec& codec); +bool IsSameCodec(const std::string& name1, + const CodecParameterMap& params1, + const std::string& name2, + const CodecParameterMap& params2); } // namespace cricket diff --git a/media/base/h264_profile_level_id.cc b/media/base/h264_profile_level_id.cc index c81921d167..4731c18f40 100644 --- a/media/base/h264_profile_level_id.cc +++ b/media/base/h264_profile_level_id.cc @@ -295,5 +295,16 @@ void GenerateProfileLevelIdForAnswer( ProfileLevelId(local_profile_level_id->profile, answer_level)); } +bool IsSameH264Profile(const CodecParameterMap& params1, + const CodecParameterMap& params2) { + const rtc::Optional profile_level_id = + webrtc::H264::ParseSdpProfileLevelId(params1); + const rtc::Optional other_profile_level_id = + webrtc::H264::ParseSdpProfileLevelId(params2); + // Compare H264 profiles, but not levels. + return profile_level_id && other_profile_level_id && + profile_level_id->profile == other_profile_level_id->profile; +} + } // namespace H264 } // namespace webrtc diff --git a/media/base/h264_profile_level_id.h b/media/base/h264_profile_level_id.h index 5831ee1aec..28899e53d9 100644 --- a/media/base/h264_profile_level_id.h +++ b/media/base/h264_profile_level_id.h @@ -96,6 +96,11 @@ void GenerateProfileLevelIdForAnswer( const CodecParameterMap& remote_offered_params, CodecParameterMap* answer_params); +// Returns true if the parameters have the same H264 profile, i.e. the same +// H264::Profile (Baseline, High, etc). +bool IsSameH264Profile(const CodecParameterMap& params1, + const CodecParameterMap& params2); + } // namespace H264 } // namespace webrtc diff --git a/media/engine/convert_legacy_video_factory.cc b/media/engine/convert_legacy_video_factory.cc index 4e92c82215..a5b46f81ab 100644 --- a/media/engine/convert_legacy_video_factory.cc +++ b/media/engine/convert_legacy_video_factory.cc @@ -33,30 +33,14 @@ namespace cricket { namespace { -bool IsSameFormat(const webrtc::SdpVideoFormat& format1, - const webrtc::SdpVideoFormat& format2) { - // If different names (case insensitive), then not same formats. - if (!CodecNamesEq(format1.name, format2.name)) - return false; - // For every format besides H264, comparing names is enough. - if (!CodecNamesEq(format1.name.c_str(), kH264CodecName)) - return true; - // Compare H264 profiles. - const rtc::Optional profile_level_id = - webrtc::H264::ParseSdpProfileLevelId(format1.parameters); - const rtc::Optional other_profile_level_id = - webrtc::H264::ParseSdpProfileLevelId(format2.parameters); - // Compare H264 profiles, but not levels. - return profile_level_id && other_profile_level_id && - profile_level_id->profile == other_profile_level_id->profile; -} - bool IsFormatSupported( const std::vector& supported_formats, const webrtc::SdpVideoFormat& format) { for (const webrtc::SdpVideoFormat& supported_format : supported_formats) { - if (IsSameFormat(format, supported_format)) + if (IsSameCodec(format.name, format.parameters, supported_format.name, + supported_format.parameters)) { return true; + } } return false; } diff --git a/sdk/android/src/jni/hardwarevideoencoderfactory.cc b/sdk/android/src/jni/hardwarevideoencoderfactory.cc index c58b4b2737..baeb426cdf 100644 --- a/sdk/android/src/jni/hardwarevideoencoderfactory.cc +++ b/sdk/android/src/jni/hardwarevideoencoderfactory.cc @@ -18,25 +18,14 @@ namespace webrtc { namespace jni { -static bool IsSameH264Profile(const cricket::CodecParameterMap& params1, - const cricket::CodecParameterMap& params2) { - const rtc::Optional profile_level_id = - H264::ParseSdpProfileLevelId(params1); - const rtc::Optional other_profile_level_id = - H264::ParseSdpProfileLevelId(params2); - // Compare H264 profiles, but not levels. - return profile_level_id && other_profile_level_id && - profile_level_id->profile == other_profile_level_id->profile; -} - JNI_FUNCTION_DECLARATION(jboolean, HardwareVideoEncoderFactory_isSameH264Profile, JNIEnv* jni, jclass, jobject params1, jobject params2) { - return IsSameH264Profile(JavaToStdMapStrings(jni, params1), - JavaToStdMapStrings(jni, params2)); + return H264::IsSameH264Profile(JavaToStdMapStrings(jni, params1), + JavaToStdMapStrings(jni, params2)); } } // namespace jni