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:

committed by
Commit Bot

parent
3ebed36b01
commit
fb1a8661db
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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");
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user