Update list of supported Android codecs based on field trial dynamically.

Currently filed trial value which controls H.264 high profile support is
read once only when factory is created. If field trial value is changed for
the next WebRTC call supported codec list need to be updated as well.

BUG=b/34816463

Review-Url: https://codereview.webrtc.org/2685183004
Cr-Commit-Position: refs/heads/master@{#16543}
This commit is contained in:
glaznev 2017-02-10 14:40:57 -08:00 committed by Commit bot
parent 9238245d9b
commit abdc857967
2 changed files with 31 additions and 29 deletions

View File

@ -1215,32 +1215,6 @@ MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory()
supported_codecs_.push_back(cricket::VideoCodec("VP9"));
}
// Check if high profile is supported by decoder. If yes, encoder can always
// fall back to baseline profile as a subset as high profile.
bool is_h264_high_profile_hw_supported = false;
if (webrtc::field_trial::FindFullName(kH264HighProfileFieldTrial) ==
"Enabled") {
is_h264_high_profile_hw_supported = jni->CallStaticBooleanMethod(
j_decoder_class,
GetStaticMethodID(jni, j_decoder_class, "isH264HighProfileHwSupported",
"()Z"));
CHECK_EXCEPTION(jni);
}
if (is_h264_high_profile_hw_supported) {
ALOGD << "H.264 High Profile HW Encoder supported.";
// TODO(magjed): Enumerate actual level instead of using hardcoded level
// 3.1. Level 3.1 is 1280x720@30fps which is enough for now.
cricket::VideoCodec constrained_high(cricket::kH264CodecName);
const webrtc::H264::ProfileLevelId constrained_high_profile(
webrtc::H264::kProfileConstrainedHigh, webrtc::H264::kLevel3_1);
constrained_high.SetParam(
cricket::kH264FmtpProfileLevelId,
*webrtc::H264::ProfileLevelIdToString(constrained_high_profile));
constrained_high.SetParam(cricket::kH264FmtpLevelAsymmetryAllowed, "1");
constrained_high.SetParam(cricket::kH264FmtpPacketizationMode, "1");
supported_codecs_.push_back(constrained_high);
}
bool is_h264_hw_supported = jni->CallStaticBooleanMethod(
j_encoder_class,
GetStaticMethodID(jni, j_encoder_class, "isH264HwSupported", "()Z"));
@ -1261,6 +1235,29 @@ MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory()
constrained_baseline.SetParam(cricket::kH264FmtpPacketizationMode, "1");
supported_codecs_.push_back(constrained_baseline);
}
// Check if high profile is supported by decoder. If yes, encoder can always
// fall back to baseline profile as a subset as high profile.
supported_codecs_with_h264_hp_ = supported_codecs_;
bool is_h264_high_profile_hw_supported = jni->CallStaticBooleanMethod(
j_decoder_class,
GetStaticMethodID(jni, j_decoder_class, "isH264HighProfileHwSupported",
"()Z"));
CHECK_EXCEPTION(jni);
if (is_h264_high_profile_hw_supported) {
ALOGD << "H.264 High Profile HW Encoder supported.";
// TODO(magjed): Enumerate actual level instead of using hardcoded level
// 3.1. Level 3.1 is 1280x720@30fps which is enough for now.
cricket::VideoCodec constrained_high(cricket::kH264CodecName);
const webrtc::H264::ProfileLevelId constrained_high_profile(
webrtc::H264::kProfileConstrainedHigh, webrtc::H264::kLevel3_1);
constrained_high.SetParam(
cricket::kH264FmtpProfileLevelId,
*webrtc::H264::ProfileLevelIdToString(constrained_high_profile));
constrained_high.SetParam(cricket::kH264FmtpLevelAsymmetryAllowed, "1");
constrained_high.SetParam(cricket::kH264FmtpPacketizationMode, "1");
supported_codecs_with_h264_hp_.push_back(constrained_high);
}
}
MediaCodecVideoEncoderFactory::~MediaCodecVideoEncoderFactory() {
@ -1286,11 +1283,11 @@ void MediaCodecVideoEncoderFactory::SetEGLContext(
webrtc::VideoEncoder* MediaCodecVideoEncoderFactory::CreateVideoEncoder(
const cricket::VideoCodec& codec) {
if (supported_codecs_.empty()) {
if (supported_codecs().empty()) {
ALOGW << "No HW video encoder for codec " << codec.name;
return nullptr;
}
if (FindMatchingCodec(supported_codecs_, codec)) {
if (FindMatchingCodec(supported_codecs(), codec)) {
ALOGD << "Create HW video encoder for " << codec.name;
JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(jni);
@ -1302,7 +1299,11 @@ webrtc::VideoEncoder* MediaCodecVideoEncoderFactory::CreateVideoEncoder(
const std::vector<cricket::VideoCodec>&
MediaCodecVideoEncoderFactory::supported_codecs() const {
return supported_codecs_;
if (webrtc::field_trial::FindFullName(kH264HighProfileFieldTrial) ==
"Enabled")
return supported_codecs_with_h264_hp_;
else
return supported_codecs_;
}
void MediaCodecVideoEncoderFactory::DestroyVideoEncoder(

View File

@ -42,6 +42,7 @@ class MediaCodecVideoEncoderFactory
// Empty if platform support is lacking, const after ctor returns.
std::vector<cricket::VideoCodec> supported_codecs_;
std::vector<cricket::VideoCodec> supported_codecs_with_h264_hp_;
};
} // namespace webrtc_jni