Create common helper method for comparing video formats

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 <magjed@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20853}
This commit is contained in:
Magnus Jedvert
2017-11-23 13:24:53 +01:00
committed by Commit Bot
parent 01f2ec35a6
commit 523589dbd8
6 changed files with 41 additions and 50 deletions

View File

@ -21,17 +21,6 @@
namespace cricket {
static bool IsSameH264Profile(const CodecParameterMap& params1,
const CodecParameterMap& params2) {
const rtc::Optional<webrtc::H264::ProfileLevelId> profile_level_id =
webrtc::H264::ParseSdpProfileLevelId(params1);
const rtc::Optional<webrtc::H264::ProfileLevelId> 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<VideoCodec>& 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 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

View File

@ -254,6 +254,10 @@ bool HasTransportCc(const Codec& codec);
const VideoCodec* FindMatchingCodec(
const std::vector<VideoCodec>& supported_codecs,
const VideoCodec& codec);
bool IsSameCodec(const std::string& name1,
const CodecParameterMap& params1,
const std::string& name2,
const CodecParameterMap& params2);
} // namespace cricket

View File

@ -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<webrtc::H264::ProfileLevelId> profile_level_id =
webrtc::H264::ParseSdpProfileLevelId(params1);
const rtc::Optional<webrtc::H264::ProfileLevelId> 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

View File

@ -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

View File

@ -33,31 +33,15 @@ 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<webrtc::H264::ProfileLevelId> profile_level_id =
webrtc::H264::ParseSdpProfileLevelId(format1.parameters);
const rtc::Optional<webrtc::H264::ProfileLevelId> 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<webrtc::SdpVideoFormat>& 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;
}

View File

@ -18,24 +18,13 @@
namespace webrtc {
namespace jni {
static bool IsSameH264Profile(const cricket::CodecParameterMap& params1,
const cricket::CodecParameterMap& params2) {
const rtc::Optional<H264::ProfileLevelId> profile_level_id =
H264::ParseSdpProfileLevelId(params1);
const rtc::Optional<H264::ProfileLevelId> 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),
return H264::IsSameH264Profile(JavaToStdMapStrings(jni, params1),
JavaToStdMapStrings(jni, params2));
}