Add support for H.264 constrained high profile in VideoProcessor.

BUG=webrtc:8448

Change-Id: I968d6cd78dd4f3c19a7944ae4cc73c5eddb9a949
Reviewed-on: https://webrtc-review.googlesource.com/16160
Commit-Queue: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20466}
This commit is contained in:
Rasmus Brandt
2017-10-27 14:51:46 +02:00
committed by Commit Bot
parent 3ebed36b01
commit fb1a8661db
8 changed files with 97 additions and 13 deletions

View File

@ -444,6 +444,7 @@ if (rtc_include_tests) {
"../../api:video_frame_api",
"../../common_video",
"../../media:rtc_audio_video",
"../../media:rtc_media_base",
"../../rtc_base:rtc_base_approved",
"../../rtc_base:rtc_base_tests_utils",
"../../system_wrappers",

View File

@ -12,6 +12,7 @@ specific_include_rules = {
"+sdk",
],
"(.*test\.cc|.*test\.h|.*test\.mm)": [
"+media/base",
"+media/engine",
"+sdk",
],

View File

@ -179,5 +179,19 @@ std::string TestConfig::ToString() const {
return ss.str();
}
std::string TestConfig::CodecName() const {
std::string codec_name = CodecTypeToPayloadString(codec_settings.codecType);
if (codec_settings.codecType == kVideoCodecH264) {
if (h264_codec_settings.profile == H264::kProfileConstrainedHigh) {
codec_name += "-CHP";
} else {
RTC_DCHECK_EQ(h264_codec_settings.profile,
H264::kProfileConstrainedBaseline);
codec_name += "-CBP";
}
}
return codec_name;
}
} // namespace test
} // namespace webrtc

View File

@ -56,6 +56,7 @@ struct TestConfig {
int TemporalLayerForFrame(int frame_idx) const;
std::vector<FrameType> FrameTypeForFrame(int frame_idx) const;
std::string ToString() const;
std::string CodecName() const;
// Plain name of YUV file to process without file extension.
std::string filename;
@ -99,6 +100,13 @@ struct TestConfig {
// Codec settings to use.
webrtc::VideoCodec codec_settings;
// H.264 specific settings.
struct H264CodecSettings {
H264::Profile profile = H264::kProfileConstrainedBaseline;
H264PacketizationMode packetization_mode =
webrtc::H264PacketizationMode::NonInterleaved;
} h264_codec_settings;
// Should hardware accelerated codecs be used?
bool hw_encoder = false;
bool hw_decoder = false;
@ -107,10 +115,6 @@ struct TestConfig {
bool sw_fallback_encoder = false;
bool sw_fallback_decoder = false;
// RTP H264 packetization mode.
H264PacketizationMode packetization_mode =
webrtc::H264PacketizationMode::NonInterleaved;
// Custom checker that will be called for each frame.
const EncodedFrameChecker* encoded_frame_checker = nullptr;
};

View File

@ -21,6 +21,8 @@
#include "modules/video_coding/codecs/test/objc_codec_h264_test.h"
#endif
#include "common_types.h" // NOLINT(build/include)
#include "media/base/h264_profile_level_id.h"
#include "media/engine/internaldecoderfactory.h"
#include "media/engine/internalencoderfactory.h"
#include "media/engine/videodecodersoftwarefallbackwrapper.h"
@ -328,12 +330,27 @@ void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() {
decoder_factory->CreateVideoDecoderWithParams(codec, decoder_params));
break;
case kVideoCodecH264:
// TODO(brandtr): Generalize so that we support multiple profiles here.
codec = cricket::VideoCodec(cricket::kH264CodecName);
if (config_.packetization_mode == H264PacketizationMode::NonInterleaved) {
if (config_.h264_codec_settings.profile ==
H264::kProfileConstrainedHigh) {
const H264::ProfileLevelId constrained_high_profile(
H264::kProfileConstrainedHigh, H264::kLevel3_1);
codec.SetParam(cricket::kH264FmtpProfileLevelId,
*H264::ProfileLevelIdToString(constrained_high_profile));
} else {
RTC_CHECK_EQ(config_.h264_codec_settings.profile,
H264::kProfileConstrainedBaseline);
const H264::ProfileLevelId constrained_baseline_profile(
H264::kProfileConstrainedBaseline, H264::kLevel3_1);
codec.SetParam(
cricket::kH264FmtpProfileLevelId,
*H264::ProfileLevelIdToString(constrained_baseline_profile));
}
if (config_.h264_codec_settings.packetization_mode ==
H264PacketizationMode::NonInterleaved) {
codec.SetParam(cricket::kH264FmtpPacketizationMode, "1");
} else {
RTC_CHECK_EQ(config_.packetization_mode,
RTC_CHECK_EQ(config_.h264_codec_settings.packetization_mode,
H264PacketizationMode::SingleNalUnit);
codec.SetParam(cricket::kH264FmtpPacketizationMode, "0");
}
@ -577,8 +594,7 @@ void VideoProcessorIntegrationTest::PrintSettings() const {
const char* decoder_name = decoder_->ImplementationName();
printf(" Decoder implementation name: %s\n", decoder_name);
if (strcmp(encoder_name, decoder_name) == 0) {
printf(" Codec implementation name : %s_%s\n",
CodecTypeToPayloadString(config_.codec_settings.codecType),
printf(" Codec implementation name : %s_%s\n", config_.CodecName().c_str(),
encoder_name);
}
printf("\n");

View File

@ -12,6 +12,7 @@
#include <vector>
#include "common_types.h" // NOLINT(build/include)
#include "test/field_trial.h"
#include "test/testsupport/fileutils.h"
@ -58,7 +59,7 @@ TEST_F(VideoProcessorIntegrationTestMediaCodec, ForemanCif500kbpsVp8) {
kNoVisualizationParams);
}
TEST_F(VideoProcessorIntegrationTestMediaCodec, ForemanCif500kbpsH264) {
TEST_F(VideoProcessorIntegrationTestMediaCodec, ForemanCif500kbpsH264CBP) {
config_.encoded_frame_checker = &h264_keyframe_checker_;
config_.SetCodecSettings(kVideoCodecH264, 1, false, false, false, false,
false, 352, 288);
@ -78,6 +79,31 @@ TEST_F(VideoProcessorIntegrationTestMediaCodec, ForemanCif500kbpsH264) {
kNoVisualizationParams);
}
// TODO(brandtr): Enable this test when we have trybots/buildbots with
// HW encoders that support CHP.
TEST_F(VideoProcessorIntegrationTestMediaCodec,
DISABLED_ForemanCif500kbpsH264CHP) {
ScopedFieldTrials override_field_trials("WebRTC-H264HighProfile/Enabled/");
config_.h264_codec_settings.profile = H264::kProfileConstrainedHigh;
config_.encoded_frame_checker = &h264_keyframe_checker_;
config_.SetCodecSettings(kVideoCodecH264, 1, false, false, false, false,
false, 352, 288);
std::vector<RateProfile> rate_profiles = {{500, 30, kForemanNumFrames + 1}};
// The thresholds below may have to be tweaked to let even poor MediaCodec
// implementations pass. If this test fails on the bots, disable it and
// ping brandtr@.
std::vector<RateControlThresholds> rc_thresholds = {{5, 60, 20, 5, 15, 0, 1}};
QualityThresholds quality_thresholds(33.0, 30.0, 0.90, 0.85);
ProcessFramesAndMaybeVerify(rate_profiles, &rc_thresholds,
&quality_thresholds, nullptr,
kNoVisualizationParams);
}
TEST_F(VideoProcessorIntegrationTestMediaCodec,
Foreman240p100kbpsVp8WithForcedSwFallback) {
ScopedFieldTrials override_field_trials(

View File

@ -73,7 +73,8 @@ TEST_F(VideoProcessorIntegrationTestOpenH264, Process0PercentPacketLoss) {
// H264: Enable SingleNalUnit packetization mode. Encoder should split
// large frames into multiple slices and limit length of NAL units.
TEST_F(VideoProcessorIntegrationTestOpenH264, ProcessNoLossSingleNalUnit) {
config_.packetization_mode = H264PacketizationMode::SingleNalUnit;
config_.h264_codec_settings.packetization_mode =
H264PacketizationMode::SingleNalUnit;
config_.networking_config.max_payload_size_in_bytes = 500;
config_.SetCodecSettings(kVideoCodecH264, 1, false, false, true, false,
kResilienceOn, kCifWidth, kCifHeight);

View File

@ -12,6 +12,7 @@
#include <vector>
#include "test/field_trial.h"
#include "test/testsupport/fileutils.h"
namespace webrtc {
@ -40,9 +41,10 @@ class VideoProcessorIntegrationTestVideoToolbox
};
// Since we don't currently run the iOS tests on physical devices on the bots,
// this test is disabled.
// the tests are disabled.
TEST_F(VideoProcessorIntegrationTestVideoToolbox,
DISABLED_ForemanCif500kbpsH264) {
DISABLED_ForemanCif500kbpsH264CBP) {
config_.SetCodecSettings(kVideoCodecH264, 1, false, false, false, false,
false, 352, 288);
@ -58,6 +60,25 @@ TEST_F(VideoProcessorIntegrationTestVideoToolbox,
kNoVisualizationParams);
}
TEST_F(VideoProcessorIntegrationTestVideoToolbox,
DISABLED_ForemanCif500kbpsH264CHP) {
ScopedFieldTrials override_field_trials("WebRTC-H264HighProfile/Enabled/");
config_.h264_codec_settings.profile = H264::kProfileConstrainedHigh;
config_.SetCodecSettings(kVideoCodecH264, 1, false, false, false, false,
false, 352, 288);
std::vector<RateProfile> rate_profiles = {{500, 30, kForemanNumFrames + 1}};
std::vector<RateControlThresholds> rc_thresholds = {{5, 75, 65, 60, 6, 0, 1}};
QualityThresholds quality_thresholds(30.0, 14.0, 0.86, 0.39);
ProcessFramesAndMaybeVerify(rate_profiles, &rc_thresholds,
&quality_thresholds, nullptr,
kNoVisualizationParams);
}
#endif // defined(WEBRTC_IOS)
} // namespace test