Add ability to instantiate VideoEncoderSoftwareFallback in VP tests.

* Split TestConfig::hw_codec into hw_encoder and hw_decoder.
* Add TestConfig::sw_fallback_encoder.

BUG=webrtc:6634

Review-Url: https://codereview.webrtc.org/3009963002
Cr-Commit-Position: refs/heads/master@{#19710}
This commit is contained in:
brandtr
2017-09-06 04:48:22 -07:00
committed by Commit Bot
parent 341c8e40b7
commit d635e5b8ed
7 changed files with 61 additions and 25 deletions

View File

@ -63,7 +63,8 @@ class PlotVideoProcessorIntegrationTest
TempFilename(OutputPath(), "plot_videoprocessor_integrationtest"); TempFilename(OutputPath(), "plot_videoprocessor_integrationtest");
config_.use_single_core = kUseSingleCore; config_.use_single_core = kUseSingleCore;
config_.verbose = true; config_.verbose = true;
config_.hw_codec = hw_codec_; config_.hw_encoder = hw_codec_;
config_.hw_decoder = hw_codec_;
SetCodecSettings(&config_, codec_type_, kNumTemporalLayers, SetCodecSettings(&config_, codec_type_, kNumTemporalLayers,
kErrorConcealmentOn, kDenoisingOn, kFrameDropperOn, kErrorConcealmentOn, kDenoisingOn, kFrameDropperOn,
kSpatialResizeOn, kResilienceOn, width, height); kSpatialResizeOn, kResilienceOn, width, height);

View File

@ -94,7 +94,7 @@ void PrintCodecSettings(const VideoCodec& codec_settings) {
void VerifyQpParser(const EncodedImage& encoded_frame, void VerifyQpParser(const EncodedImage& encoded_frame,
const TestConfig& config) { const TestConfig& config) {
if (config.hw_codec) if (config.hw_encoder)
return; return;
int qp; int qp;

View File

@ -93,8 +93,14 @@ struct TestConfig {
// If printing of information to stdout shall be performed during processing. // If printing of information to stdout shall be performed during processing.
bool verbose = true; bool verbose = true;
// If HW or SW codec should be used. // Should hardware accelerated codecs be used?
bool hw_codec = false; bool hw_encoder = false;
bool hw_decoder = false;
// Should the hardware codecs be wrapped in software fallbacks?
bool sw_fallback_encoder = false;
// TODO(brandtr): Add support for SW decoder fallbacks, when
// webrtc::VideoDecoder's can be wrapped in std::unique_ptr's.
}; };
// Handles encoding/decoding of video using the VideoEncoder/VideoDecoder // Handles encoding/decoding of video using the VideoEncoder/VideoDecoder

View File

@ -22,6 +22,7 @@
#include "webrtc/media/engine/internaldecoderfactory.h" #include "webrtc/media/engine/internaldecoderfactory.h"
#include "webrtc/media/engine/internalencoderfactory.h" #include "webrtc/media/engine/internalencoderfactory.h"
#include "webrtc/media/engine/videoencodersoftwarefallbackwrapper.h"
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h"
#include "webrtc/modules/video_coding/include/video_codec_interface.h" #include "webrtc/modules/video_coding/include/video_codec_interface.h"
#include "webrtc/modules/video_coding/include/video_coding.h" #include "webrtc/modules/video_coding/include/video_coding.h"
@ -89,8 +90,12 @@ void VideoProcessorIntegrationTest::SetCodecSettings(TestConfig* config,
int width, int width,
int height) { int height) {
webrtc::test::CodecSettings(codec_type, &config->codec_settings); webrtc::test::CodecSettings(codec_type, &config->codec_settings);
// TODO(brandtr): Move the setting of |width| and |height| to the tests, and
// DCHECK that they are set before initializing the codec instead.
config->codec_settings.width = width; config->codec_settings.width = width;
config->codec_settings.height = height; config->codec_settings.height = height;
switch (config->codec_settings.codecType) { switch (config->codec_settings.codecType) {
case kVideoCodecVP8: case kVideoCodecVP8:
config->codec_settings.VP8()->resilience = config->codec_settings.VP8()->resilience =
@ -186,7 +191,7 @@ void VideoProcessorIntegrationTest::ProcessFramesAndMaybeVerify(
// MediaCodec API, we roughly pace the frames here. The downside // MediaCodec API, we roughly pace the frames here. The downside
// of this is that the encode run will be done in real-time. // of this is that the encode run will be done in real-time.
// TODO(brandtr): Investigate if this is needed on iOS. // TODO(brandtr): Investigate if this is needed on iOS.
if (config_.hw_codec) { if (config_.hw_encoder || config_.hw_decoder) {
SleepMs(rtc::kNumMillisecsPerSec / SleepMs(rtc::kNumMillisecsPerSec /
rate_profile.input_frame_rate[rate_update_index]); rate_profile.input_frame_rate[rate_update_index]);
} }
@ -207,7 +212,7 @@ void VideoProcessorIntegrationTest::ProcessFramesAndMaybeVerify(
// Give the VideoProcessor pipeline some time to process the last frame, // Give the VideoProcessor pipeline some time to process the last frame,
// and then release the codecs. // and then release the codecs.
if (config_.hw_codec) { if (config_.hw_encoder || config_.hw_decoder) {
SleepMs(1 * rtc::kNumMillisecsPerSec); SleepMs(1 * rtc::kNumMillisecsPerSec);
} }
ReleaseAndCloseObjects(&task_queue); ReleaseAndCloseObjects(&task_queue);
@ -269,41 +274,55 @@ void VideoProcessorIntegrationTest::ProcessFramesAndMaybeVerify(
} }
void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() { void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() {
if (config_.hw_codec) { std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory;
if (config_.hw_encoder) {
#if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED)
#if defined(WEBRTC_ANDROID)
encoder_factory.reset(new jni::MediaCodecVideoEncoderFactory());
#elif defined(WEBRTC_IOS)
EXPECT_EQ(kVideoCodecH264, config_.codec_settings.codecType)
<< "iOS HW codecs only support H264.";
encoder_factory = CreateObjCEncoderFactory();
#else
RTC_NOTREACHED() << "Only support HW encoder on Android and iOS.";
#endif
#endif // WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED
} else {
encoder_factory.reset(new cricket::InternalEncoderFactory());
}
if (config_.hw_decoder) {
#if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED)
#if defined(WEBRTC_ANDROID) #if defined(WEBRTC_ANDROID)
encoder_factory_.reset(new jni::MediaCodecVideoEncoderFactory());
decoder_factory_.reset(new jni::MediaCodecVideoDecoderFactory()); decoder_factory_.reset(new jni::MediaCodecVideoDecoderFactory());
#elif defined(WEBRTC_IOS) #elif defined(WEBRTC_IOS)
EXPECT_EQ(kVideoCodecH264, config_.codec_settings.codecType) EXPECT_EQ(kVideoCodecH264, config_.codec_settings.codecType)
<< "iOS HW codecs only support H264."; << "iOS HW codecs only support H264.";
encoder_factory_ = CreateObjCEncoderFactory();
decoder_factory_ = CreateObjCDecoderFactory(); decoder_factory_ = CreateObjCDecoderFactory();
#else #else
RTC_NOTREACHED() << "Only support HW codecs on Android and iOS."; RTC_NOTREACHED() << "Only support HW decoder on Android and iOS.";
#endif #endif
#endif // WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED #endif // WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED
} else { } else {
// SW codecs.
encoder_factory_.reset(new cricket::InternalEncoderFactory());
decoder_factory_.reset(new cricket::InternalDecoderFactory()); decoder_factory_.reset(new cricket::InternalDecoderFactory());
} }
cricket::VideoCodec encoder_codec;
switch (config_.codec_settings.codecType) { switch (config_.codec_settings.codecType) {
case kVideoCodecVP8: case kVideoCodecVP8:
encoder_ = encoder_factory_->CreateVideoEncoder( encoder_codec = cricket::VideoCodec(cricket::kVp8CodecName);
cricket::VideoCodec(cricket::kVp8CodecName)); encoder_.reset(encoder_factory->CreateVideoEncoder(encoder_codec));
decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecVP8); decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecVP8);
break; break;
case kVideoCodecVP9: case kVideoCodecVP9:
encoder_ = encoder_factory_->CreateVideoEncoder( encoder_codec = cricket::VideoCodec(cricket::kVp9CodecName);
cricket::VideoCodec(cricket::kVp9CodecName)); encoder_.reset(encoder_factory->CreateVideoEncoder(encoder_codec));
decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecVP9); decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecVP9);
break; break;
case kVideoCodecH264: case kVideoCodecH264:
// TODO(brandtr): Generalize so that we support multiple profiles here. // TODO(brandtr): Generalize so that we support multiple profiles here.
encoder_ = encoder_factory_->CreateVideoEncoder( encoder_codec = cricket::VideoCodec(cricket::kH264CodecName);
cricket::VideoCodec(cricket::kH264CodecName)); encoder_.reset(encoder_factory->CreateVideoEncoder(encoder_codec));
decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecH264); decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecH264);
break; break;
default: default:
@ -311,12 +330,17 @@ void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() {
break; break;
} }
if (config_.sw_fallback_encoder) {
encoder_ = rtc::MakeUnique<VideoEncoderSoftwareFallbackWrapper>(
encoder_codec, std::move(encoder_));
}
EXPECT_TRUE(encoder_) << "Encoder not successfully created."; EXPECT_TRUE(encoder_) << "Encoder not successfully created.";
EXPECT_TRUE(decoder_) << "Decoder not successfully created."; EXPECT_TRUE(decoder_) << "Decoder not successfully created.";
} }
void VideoProcessorIntegrationTest::DestroyEncoderAndDecoder() { void VideoProcessorIntegrationTest::DestroyEncoderAndDecoder() {
encoder_factory_->DestroyVideoEncoder(encoder_); encoder_.reset();
decoder_factory_->DestroyVideoDecoder(decoder_); decoder_factory_->DestroyVideoDecoder(decoder_);
} }
@ -340,7 +364,7 @@ void VideoProcessorIntegrationTest::SetUpAndInitObjects(
if (visualization_params) { if (visualization_params) {
const std::string codec_name = const std::string codec_name =
CodecTypeToPayloadString(config_.codec_settings.codecType); CodecTypeToPayloadString(config_.codec_settings.codecType);
const std::string implementation_type = config_.hw_codec ? "hw" : "sw"; const std::string implementation_type = config_.hw_encoder ? "hw" : "sw";
// clang-format off // clang-format off
const std::string output_filename_base = const std::string output_filename_base =
OutputPath() + config_.filename + "-" + OutputPath() + config_.filename + "-" +
@ -370,8 +394,12 @@ void VideoProcessorIntegrationTest::SetUpAndInitObjects(
rtc::Event sync_event(false, false); rtc::Event sync_event(false, false);
task_queue->PostTask([this, &sync_event]() { task_queue->PostTask([this, &sync_event]() {
// TODO(brandtr): std::move |encoder_| and |decoder_| into the
// VideoProcessor when we are able to store |decoder_| in a
// std::unique_ptr. That is, when https://codereview.webrtc.org/3009973002
// has been relanded.
processor_ = rtc::MakeUnique<VideoProcessor>( processor_ = rtc::MakeUnique<VideoProcessor>(
encoder_, decoder_, analysis_frame_reader_.get(), encoder_.get(), decoder_, analysis_frame_reader_.get(),
analysis_frame_writer_.get(), packet_manipulator_.get(), config_, analysis_frame_writer_.get(), packet_manipulator_.get(), config_,
&stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get()); &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get());
processor_->Init(); processor_->Init();

View File

@ -150,8 +150,7 @@ class VideoProcessorIntegrationTest : public testing::Test {
const RateProfile& rate_profile); const RateProfile& rate_profile);
// Codecs. // Codecs.
std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory_; std::unique_ptr<VideoEncoder> encoder_;
VideoEncoder* encoder_;
std::unique_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory_; std::unique_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory_;
VideoDecoder* decoder_; VideoDecoder* decoder_;

View File

@ -44,7 +44,8 @@ class VideoProcessorIntegrationTestLibvpx
// Only allow encoder/decoder to use single core, for predictability. // Only allow encoder/decoder to use single core, for predictability.
config_.use_single_core = true; config_.use_single_core = true;
config_.verbose = false; config_.verbose = false;
config_.hw_codec = false; config_.hw_encoder = false;
config_.hw_decoder = false;
} }
}; };

View File

@ -43,7 +43,8 @@ class VideoProcessorIntegrationTestOpenH264
// Only allow encoder/decoder to use single core, for predictability. // Only allow encoder/decoder to use single core, for predictability.
config_.use_single_core = true; config_.use_single_core = true;
config_.verbose = false; config_.verbose = false;
config_.hw_codec = false; config_.hw_encoder = false;
config_.hw_decoder = false;
} }
}; };