Make rtc_software_fallback_wrappers target visible.

Need to depend on them from Chromium.

Bug: webrtc:7925
Change-Id: Iea1bb3b937c602920bfd87f885c87c790ac7bc17
Reviewed-on: https://webrtc-review.googlesource.com/82061
Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Anders Carlsson <andersc@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23580}
This commit is contained in:
Anders Carlsson
2018-06-12 11:15:56 +02:00
committed by Commit Bot
parent cf15eb57ff
commit dd3e0ab2bf
18 changed files with 340 additions and 304 deletions

View File

@ -435,7 +435,7 @@ if (rtc_include_tests) {
"api:rtc_api_unittests", "api:rtc_api_unittests",
"api/audio/test:audio_api_unittests", "api/audio/test:audio_api_unittests",
"api/audio_codecs/test:audio_codecs_api_unittests", "api/audio_codecs/test:audio_codecs_api_unittests",
"api/video_codecs/test:builtin_video_codec_factory_unittests", "api/video_codecs/test:video_codecs_api_unittests",
"p2p:libstunprober_unittests", "p2p:libstunprober_unittests",
"p2p:rtc_p2p_unittests", "p2p:rtc_p2p_unittests",
"rtc_base:rtc_base_approved_unittests", "rtc_base:rtc_base_approved_unittests",

View File

@ -6,6 +6,7 @@ include_rules = [
"+pc", "+pc",
"+logging/rtc_event_log/rtc_event_log_factory_interface.h", "+logging/rtc_event_log/rtc_event_log_factory_interface.h",
"+modules/audio_processing/include", "+modules/audio_processing/include",
"+system_wrappers/include",
] ]
specific_include_rules = { specific_include_rules = {

View File

@ -76,3 +76,31 @@ rtc_static_library("builtin_video_encoder_factory") {
"../../rtc_base:ptr_util", "../../rtc_base:ptr_util",
] ]
} }
rtc_static_library("rtc_software_fallback_wrappers") {
visibility = [ "*" ]
sources = [
"video_decoder_software_fallback_wrapper.cc",
"video_decoder_software_fallback_wrapper.h",
"video_encoder_software_fallback_wrapper.cc",
"video_encoder_software_fallback_wrapper.h",
]
if (!build_with_chromium && is_clang) {
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
}
deps = [
":video_codecs_api",
"../../media:rtc_h264_profile_id",
"../../media:rtc_media_base",
"../../modules/video_coding:video_codec_interface",
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",
"../../rtc_base/system:fallthrough",
"../../system_wrappers:field_trial_api",
"../video:video_bitrate_allocation",
]
}

View File

@ -9,18 +9,28 @@
import("../../../webrtc.gni") import("../../../webrtc.gni")
if (rtc_include_tests) { if (rtc_include_tests) {
rtc_source_set("builtin_video_codec_factory_unittests") { rtc_source_set("video_codecs_api_unittests") {
testonly = true testonly = true
sources = [ sources = [
"builtin_video_encoder_factory_unittest.cc", "builtin_video_encoder_factory_unittest.cc",
"video_decoder_software_fallback_wrapper_unittest.cc",
"video_encoder_software_fallback_wrapper_unittest.cc",
] ]
deps = [ deps = [
"..:builtin_video_encoder_factory", "..:builtin_video_encoder_factory",
"..:rtc_software_fallback_wrappers",
"..:video_codecs_api", "..:video_codecs_api",
"../../../modules/video_coding:video_codec_interface",
"../../../modules/video_coding:webrtc_vp8",
"../../../modules/video_coding:webrtc_vp8_helpers",
"../../../rtc_base:checks",
"../../../rtc_base:rtc_base_tests_utils",
"../../../system_wrappers:metrics_default", "../../../system_wrappers:metrics_default",
"../../../test:field_trial", "../../../test:field_trial",
"../../../test:test_support", "../../../test:test_support",
"../../video:video_bitrate_allocation",
"../../video:video_frame_i420",
"//testing/gtest", "//testing/gtest",
] ]
} }

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "media/engine/videodecodersoftwarefallbackwrapper.h" #include "api/video_codecs/video_decoder_software_fallback_wrapper.h"
#include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_decoder.h"
#include "modules/video_coding/codecs/vp8/include/vp8.h" #include "modules/video_coding/codecs/vp8/include/vp8.h"
#include "modules/video_coding/include/video_error_codes.h" #include "modules/video_coding/include/video_error_codes.h"
@ -21,8 +21,9 @@ class VideoDecoderSoftwareFallbackWrapperTest : public ::testing::Test {
protected: protected:
VideoDecoderSoftwareFallbackWrapperTest() VideoDecoderSoftwareFallbackWrapperTest()
: fake_decoder_(new CountingFakeDecoder()), : fake_decoder_(new CountingFakeDecoder()),
fallback_wrapper_(std::unique_ptr<VideoDecoder>(VP8Decoder::Create()), fallback_wrapper_(CreateVideoDecoderSoftwareFallbackWrapper(
std::unique_ptr<VideoDecoder>(fake_decoder_)) {} std::unique_ptr<VideoDecoder>(VP8Decoder::Create()),
std::unique_ptr<VideoDecoder>(fake_decoder_))) {}
class CountingFakeDecoder : public VideoDecoder { class CountingFakeDecoder : public VideoDecoder {
public: public:
@ -51,9 +52,7 @@ class VideoDecoderSoftwareFallbackWrapperTest : public ::testing::Test {
return WEBRTC_VIDEO_CODEC_OK; return WEBRTC_VIDEO_CODEC_OK;
} }
const char* ImplementationName() const override { const char* ImplementationName() const override { return "fake-decoder"; }
return "fake-decoder";
}
int init_decode_count_ = 0; int init_decode_count_ = 0;
int decode_count_ = 0; int decode_count_ = 0;
@ -65,17 +64,17 @@ class VideoDecoderSoftwareFallbackWrapperTest : public ::testing::Test {
}; };
// |fake_decoder_| is owned and released by |fallback_wrapper_|. // |fake_decoder_| is owned and released by |fallback_wrapper_|.
CountingFakeDecoder* fake_decoder_; CountingFakeDecoder* fake_decoder_;
VideoDecoderSoftwareFallbackWrapper fallback_wrapper_; std::unique_ptr<VideoDecoder> fallback_wrapper_;
}; };
TEST_F(VideoDecoderSoftwareFallbackWrapperTest, InitializesDecoder) { TEST_F(VideoDecoderSoftwareFallbackWrapperTest, InitializesDecoder) {
VideoCodec codec = {}; VideoCodec codec = {};
fallback_wrapper_.InitDecode(&codec, 2); fallback_wrapper_->InitDecode(&codec, 2);
EXPECT_EQ(1, fake_decoder_->init_decode_count_); EXPECT_EQ(1, fake_decoder_->init_decode_count_);
EncodedImage encoded_image; EncodedImage encoded_image;
encoded_image._frameType = kVideoFrameKey; encoded_image._frameType = kVideoFrameKey;
fallback_wrapper_.Decode(encoded_image, false, nullptr, -1); fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
EXPECT_EQ(1, fake_decoder_->init_decode_count_) EXPECT_EQ(1, fake_decoder_->init_decode_count_)
<< "Initialized decoder should not be reinitialized."; << "Initialized decoder should not be reinitialized.";
EXPECT_EQ(1, fake_decoder_->decode_count_); EXPECT_EQ(1, fake_decoder_->decode_count_);
@ -84,14 +83,13 @@ TEST_F(VideoDecoderSoftwareFallbackWrapperTest, InitializesDecoder) {
TEST_F(VideoDecoderSoftwareFallbackWrapperTest, TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
UsesFallbackDecoderAfterAnyInitDecodeFailure) { UsesFallbackDecoderAfterAnyInitDecodeFailure) {
VideoCodec codec = {}; VideoCodec codec = {};
fake_decoder_->init_decode_return_code_ = fake_decoder_->init_decode_return_code_ = WEBRTC_VIDEO_CODEC_UNINITIALIZED;
WEBRTC_VIDEO_CODEC_UNINITIALIZED; fallback_wrapper_->InitDecode(&codec, 2);
fallback_wrapper_.InitDecode(&codec, 2);
EXPECT_EQ(1, fake_decoder_->init_decode_count_); EXPECT_EQ(1, fake_decoder_->init_decode_count_);
EncodedImage encoded_image; EncodedImage encoded_image;
encoded_image._frameType = kVideoFrameKey; encoded_image._frameType = kVideoFrameKey;
fallback_wrapper_.Decode(encoded_image, false, nullptr, -1); fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
EXPECT_EQ(1, fake_decoder_->init_decode_count_) EXPECT_EQ(1, fake_decoder_->init_decode_count_)
<< "Should not have attempted reinitializing the fallback decoder on " << "Should not have attempted reinitializing the fallback decoder on "
"keyframe."; "keyframe.";
@ -103,16 +101,16 @@ TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
TEST_F(VideoDecoderSoftwareFallbackWrapperTest, IsSoftwareFallbackSticky) { TEST_F(VideoDecoderSoftwareFallbackWrapperTest, IsSoftwareFallbackSticky) {
VideoCodec codec = {}; VideoCodec codec = {};
fallback_wrapper_.InitDecode(&codec, 2); fallback_wrapper_->InitDecode(&codec, 2);
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
EncodedImage encoded_image; EncodedImage encoded_image;
fallback_wrapper_.Decode(encoded_image, false, nullptr, -1); fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
EXPECT_EQ(1, fake_decoder_->decode_count_); EXPECT_EQ(1, fake_decoder_->decode_count_);
// Software fallback should be sticky, fake_decoder_ shouldn't be used. // Software fallback should be sticky, fake_decoder_ shouldn't be used.
encoded_image._frameType = kVideoFrameKey; encoded_image._frameType = kVideoFrameKey;
fallback_wrapper_.Decode(encoded_image, false, nullptr, -1); fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
EXPECT_EQ(1, fake_decoder_->decode_count_) EXPECT_EQ(1, fake_decoder_->decode_count_)
<< "Decoder shouldn't be used after failure."; << "Decoder shouldn't be used after failure.";
@ -122,50 +120,49 @@ TEST_F(VideoDecoderSoftwareFallbackWrapperTest, IsSoftwareFallbackSticky) {
TEST_F(VideoDecoderSoftwareFallbackWrapperTest, DoesNotFallbackOnEveryError) { TEST_F(VideoDecoderSoftwareFallbackWrapperTest, DoesNotFallbackOnEveryError) {
VideoCodec codec = {}; VideoCodec codec = {};
fallback_wrapper_.InitDecode(&codec, 2); fallback_wrapper_->InitDecode(&codec, 2);
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR; fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
EncodedImage encoded_image; EncodedImage encoded_image;
EXPECT_EQ( EXPECT_EQ(fake_decoder_->decode_return_code_,
fake_decoder_->decode_return_code_, fallback_wrapper_->Decode(encoded_image, false, nullptr, -1));
fallback_wrapper_.Decode(encoded_image, false, nullptr, -1));
EXPECT_EQ(1, fake_decoder_->decode_count_); EXPECT_EQ(1, fake_decoder_->decode_count_);
fallback_wrapper_.Decode(encoded_image, false, nullptr, -1); fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
EXPECT_EQ(2, fake_decoder_->decode_count_) EXPECT_EQ(2, fake_decoder_->decode_count_)
<< "Decoder should be active even though previous decode failed."; << "Decoder should be active even though previous decode failed.";
} }
TEST_F(VideoDecoderSoftwareFallbackWrapperTest, UsesHwDecoderAfterReinit) { TEST_F(VideoDecoderSoftwareFallbackWrapperTest, UsesHwDecoderAfterReinit) {
VideoCodec codec = {}; VideoCodec codec = {};
fallback_wrapper_.InitDecode(&codec, 2); fallback_wrapper_->InitDecode(&codec, 2);
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
EncodedImage encoded_image; EncodedImage encoded_image;
fallback_wrapper_.Decode(encoded_image, false, nullptr, -1); fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
EXPECT_EQ(1, fake_decoder_->decode_count_); EXPECT_EQ(1, fake_decoder_->decode_count_);
fallback_wrapper_.Release(); fallback_wrapper_->Release();
fallback_wrapper_.InitDecode(&codec, 2); fallback_wrapper_->InitDecode(&codec, 2);
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_OK; fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
fallback_wrapper_.Decode(encoded_image, false, nullptr, -1); fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
EXPECT_EQ(2, fake_decoder_->decode_count_) EXPECT_EQ(2, fake_decoder_->decode_count_)
<< "Should not be using fallback after reinit."; << "Should not be using fallback after reinit.";
} }
TEST_F(VideoDecoderSoftwareFallbackWrapperTest, ForwardsReleaseCall) { TEST_F(VideoDecoderSoftwareFallbackWrapperTest, ForwardsReleaseCall) {
VideoCodec codec = {}; VideoCodec codec = {};
fallback_wrapper_.InitDecode(&codec, 2); fallback_wrapper_->InitDecode(&codec, 2);
fallback_wrapper_.Release(); fallback_wrapper_->Release();
EXPECT_EQ(1, fake_decoder_->release_count_); EXPECT_EQ(1, fake_decoder_->release_count_);
fallback_wrapper_.InitDecode(&codec, 2); fallback_wrapper_->InitDecode(&codec, 2);
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
EncodedImage encoded_image; EncodedImage encoded_image;
fallback_wrapper_.Decode(encoded_image, false, nullptr, -1); fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
EXPECT_EQ(2, fake_decoder_->release_count_) EXPECT_EQ(2, fake_decoder_->release_count_)
<< "Decoder should be released during fallback."; << "Decoder should be released during fallback.";
fallback_wrapper_.Release(); fallback_wrapper_->Release();
EXPECT_EQ(2, fake_decoder_->release_count_); EXPECT_EQ(2, fake_decoder_->release_count_);
} }
@ -175,8 +172,8 @@ TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
ForwardsRegisterDecodeCompleteCallback) { ForwardsRegisterDecodeCompleteCallback) {
class FakeDecodedImageCallback : public DecodedImageCallback { class FakeDecodedImageCallback : public DecodedImageCallback {
int32_t Decoded(VideoFrame& decodedImage) override { return 0; } int32_t Decoded(VideoFrame& decodedImage) override { return 0; }
int32_t Decoded( int32_t Decoded(webrtc::VideoFrame& decodedImage,
webrtc::VideoFrame& decodedImage, int64_t decode_time_ms) override { int64_t decode_time_ms) override {
RTC_NOTREACHED(); RTC_NOTREACHED();
return -1; return -1;
} }
@ -188,24 +185,24 @@ TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
} callback; } callback;
VideoCodec codec = {}; VideoCodec codec = {};
fallback_wrapper_.InitDecode(&codec, 2); fallback_wrapper_->InitDecode(&codec, 2);
fallback_wrapper_.RegisterDecodeCompleteCallback(&callback); fallback_wrapper_->RegisterDecodeCompleteCallback(&callback);
EXPECT_EQ(&callback, fake_decoder_->decode_complete_callback_); EXPECT_EQ(&callback, fake_decoder_->decode_complete_callback_);
} }
TEST_F(VideoDecoderSoftwareFallbackWrapperTest, TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
ReportsFallbackImplementationName) { ReportsFallbackImplementationName) {
VideoCodec codec = {}; VideoCodec codec = {};
fallback_wrapper_.InitDecode(&codec, 2); fallback_wrapper_->InitDecode(&codec, 2);
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
EncodedImage encoded_image; EncodedImage encoded_image;
fallback_wrapper_.Decode(encoded_image, false, nullptr, -1); fallback_wrapper_->Decode(encoded_image, false, nullptr, -1);
// Hard coded expected value since libvpx is the software implementation name // Hard coded expected value since libvpx is the software implementation name
// for VP8. Change accordingly if the underlying implementation does. // for VP8. Change accordingly if the underlying implementation does.
EXPECT_STREQ("libvpx (fallback from: fake-decoder)", EXPECT_STREQ("libvpx (fallback from: fake-decoder)",
fallback_wrapper_.ImplementationName()); fallback_wrapper_->ImplementationName());
fallback_wrapper_.Release(); fallback_wrapper_->Release();
} }
} // namespace webrtc } // namespace webrtc

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "media/engine/videoencodersoftwarefallbackwrapper.h" #include "api/video_codecs/video_encoder_software_fallback_wrapper.h"
#include <utility> #include <utility>
@ -44,8 +44,9 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
const std::string& field_trials) const std::string& field_trials)
: override_field_trials_(field_trials), : override_field_trials_(field_trials),
fake_encoder_(new CountingFakeEncoder()), fake_encoder_(new CountingFakeEncoder()),
fallback_wrapper_(std::unique_ptr<VideoEncoder>(VP8Encoder::Create()), fallback_wrapper_(CreateVideoEncoderSoftwareFallbackWrapper(
std::unique_ptr<VideoEncoder>(fake_encoder_)) {} std::unique_ptr<VideoEncoder>(VP8Encoder::Create()),
std::unique_ptr<VideoEncoder>(fake_encoder_))) {}
class CountingFakeEncoder : public VideoEncoder { class CountingFakeEncoder : public VideoEncoder {
public: public:
@ -96,9 +97,7 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
return supports_native_handle_; return supports_native_handle_;
} }
const char* ImplementationName() const override { const char* ImplementationName() const override { return "fake-encoder"; }
return "fake-encoder";
}
VideoEncoder::ScalingSettings GetScalingSettings() const override { VideoEncoder::ScalingSettings GetScalingSettings() const override {
return VideoEncoder::ScalingSettings(kLowThreshold, kHighThreshold); return VideoEncoder::ScalingSettings(kLowThreshold, kHighThreshold);
@ -142,7 +141,7 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
FakeEncodedImageCallback callback_; FakeEncodedImageCallback callback_;
// |fake_encoder_| is owned and released by |fallback_wrapper_|. // |fake_encoder_| is owned and released by |fallback_wrapper_|.
CountingFakeEncoder* fake_encoder_; CountingFakeEncoder* fake_encoder_;
VideoEncoderSoftwareFallbackWrapper fallback_wrapper_; std::unique_ptr<VideoEncoder> fallback_wrapper_;
VideoCodec codec_ = {}; VideoCodec codec_ = {};
std::unique_ptr<VideoFrame> frame_; std::unique_ptr<VideoFrame> frame_;
std::unique_ptr<SimulcastRateAllocator> rate_allocator_; std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
@ -160,11 +159,11 @@ void VideoEncoderSoftwareFallbackWrapperTest::EncodeFrame(int expected_ret) {
frame_.reset( frame_.reset(
new VideoFrame(buffer, webrtc::kVideoRotation_0, 0 /* timestamp_us */)); new VideoFrame(buffer, webrtc::kVideoRotation_0, 0 /* timestamp_us */));
EXPECT_EQ(expected_ret, fallback_wrapper_.Encode(*frame_, nullptr, &types)); EXPECT_EQ(expected_ret, fallback_wrapper_->Encode(*frame_, nullptr, &types));
} }
void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() { void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() {
fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
EXPECT_EQ(&callback_, fake_encoder_->encode_complete_callback_); EXPECT_EQ(&callback_, fake_encoder_->encode_complete_callback_);
// Register with failing fake encoder. Should succeed with VP8 fallback. // Register with failing fake encoder. Should succeed with VP8 fallback.
@ -177,10 +176,10 @@ void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() {
fake_encoder_->init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR; fake_encoder_->init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
fallback_wrapper_.InitEncode(&codec_, kNumCores, kMaxPayloadSize)); fallback_wrapper_->InitEncode(&codec_, kNumCores, kMaxPayloadSize));
EXPECT_EQ( EXPECT_EQ(
WEBRTC_VIDEO_CODEC_OK, WEBRTC_VIDEO_CODEC_OK,
fallback_wrapper_.SetRateAllocation( fallback_wrapper_->SetRateAllocation(
rate_allocator_->GetAllocation(300000, kFramerate), kFramerate)); rate_allocator_->GetAllocation(300000, kFramerate), kFramerate));
int callback_count = callback_.callback_count_; int callback_count = callback_.callback_count_;
@ -191,17 +190,17 @@ void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() {
} }
void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() { void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() {
fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
codec_.codecType = kVideoCodecVP8; codec_.codecType = kVideoCodecVP8;
codec_.maxFramerate = kFramerate; codec_.maxFramerate = kFramerate;
codec_.width = kWidth; codec_.width = kWidth;
codec_.height = kHeight; codec_.height = kHeight;
codec_.VP8()->numberOfTemporalLayers = 1; codec_.VP8()->numberOfTemporalLayers = 1;
rate_allocator_.reset(new SimulcastRateAllocator(codec_)); rate_allocator_.reset(new SimulcastRateAllocator(codec_));
fallback_wrapper_.InitEncode(&codec_, 2, kMaxPayloadSize); fallback_wrapper_->InitEncode(&codec_, 2, kMaxPayloadSize);
EXPECT_EQ( EXPECT_EQ(
WEBRTC_VIDEO_CODEC_OK, WEBRTC_VIDEO_CODEC_OK,
fallback_wrapper_.SetRateAllocation( fallback_wrapper_->SetRateAllocation(
rate_allocator_->GetAllocation(300000, kFramerate), kFramerate)); rate_allocator_->GetAllocation(300000, kFramerate), kFramerate));
EXPECT_EQ(1, fake_encoder_->init_encode_count_); EXPECT_EQ(1, fake_encoder_->init_encode_count_);
@ -217,7 +216,7 @@ void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() {
TEST_F(VideoEncoderSoftwareFallbackWrapperTest, InitializesEncoder) { TEST_F(VideoEncoderSoftwareFallbackWrapperTest, InitializesEncoder) {
VideoCodec codec = {}; VideoCodec codec = {};
fallback_wrapper_.InitEncode(&codec, 2, kMaxPayloadSize); fallback_wrapper_->InitEncode(&codec, 2, kMaxPayloadSize);
EXPECT_EQ(1, fake_encoder_->init_encode_count_); EXPECT_EQ(1, fake_encoder_->init_encode_count_);
} }
@ -231,7 +230,7 @@ TEST_F(VideoEncoderSoftwareFallbackWrapperTest, EncodeRequestsFallback) {
TEST_F(VideoEncoderSoftwareFallbackWrapperTest, CanUtilizeFallbackEncoder) { TEST_F(VideoEncoderSoftwareFallbackWrapperTest, CanUtilizeFallbackEncoder) {
UtilizeFallbackEncoder(); UtilizeFallbackEncoder();
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
} }
TEST_F(VideoEncoderSoftwareFallbackWrapperTest, TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
@ -239,7 +238,7 @@ TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
EXPECT_EQ(0, fake_encoder_->release_count_); EXPECT_EQ(0, fake_encoder_->release_count_);
UtilizeFallbackEncoder(); UtilizeFallbackEncoder();
EXPECT_EQ(1, fake_encoder_->release_count_); EXPECT_EQ(1, fake_encoder_->release_count_);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
// No extra release when the fallback is released. // No extra release when the fallback is released.
EXPECT_EQ(1, fake_encoder_->release_count_); EXPECT_EQ(1, fake_encoder_->release_count_);
} }
@ -251,7 +250,7 @@ TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
EncodeFrame(); EncodeFrame();
EXPECT_EQ(encode_count, fake_encoder_->encode_count_); EXPECT_EQ(encode_count, fake_encoder_->encode_count_);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
} }
TEST_F(VideoEncoderSoftwareFallbackWrapperTest, TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
@ -260,55 +259,55 @@ TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
// Registering an encode-complete callback should still work when fallback // Registering an encode-complete callback should still work when fallback
// encoder is being used. // encoder is being used.
FakeEncodedImageCallback callback2; FakeEncodedImageCallback callback2;
fallback_wrapper_.RegisterEncodeCompleteCallback(&callback2); fallback_wrapper_->RegisterEncodeCompleteCallback(&callback2);
EXPECT_EQ(&callback2, fake_encoder_->encode_complete_callback_); EXPECT_EQ(&callback2, fake_encoder_->encode_complete_callback_);
// Encoding a frame using the fallback should arrive at the new callback. // Encoding a frame using the fallback should arrive at the new callback.
std::vector<FrameType> types(1, kVideoFrameKey); std::vector<FrameType> types(1, kVideoFrameKey);
frame_->set_timestamp(frame_->timestamp() + 1000); frame_->set_timestamp(frame_->timestamp() + 1000);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
fallback_wrapper_.Encode(*frame_, nullptr, &types)); fallback_wrapper_->Encode(*frame_, nullptr, &types));
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
} }
TEST_F(VideoEncoderSoftwareFallbackWrapperTest, TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
SetChannelParametersForwardedDuringFallback) { SetChannelParametersForwardedDuringFallback) {
UtilizeFallbackEncoder(); UtilizeFallbackEncoder();
EXPECT_EQ(0, fake_encoder_->set_channel_parameters_count_); EXPECT_EQ(0, fake_encoder_->set_channel_parameters_count_);
fallback_wrapper_.SetChannelParameters(1, 1); fallback_wrapper_->SetChannelParameters(1, 1);
EXPECT_EQ(1, fake_encoder_->set_channel_parameters_count_); EXPECT_EQ(1, fake_encoder_->set_channel_parameters_count_);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
} }
TEST_F(VideoEncoderSoftwareFallbackWrapperTest, TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
SetRatesForwardedDuringFallback) { SetRatesForwardedDuringFallback) {
UtilizeFallbackEncoder(); UtilizeFallbackEncoder();
EXPECT_EQ(1, fake_encoder_->set_rates_count_); EXPECT_EQ(1, fake_encoder_->set_rates_count_);
fallback_wrapper_.SetRateAllocation(VideoBitrateAllocation(), 1); fallback_wrapper_->SetRateAllocation(VideoBitrateAllocation(), 1);
EXPECT_EQ(2, fake_encoder_->set_rates_count_); EXPECT_EQ(2, fake_encoder_->set_rates_count_);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
} }
TEST_F(VideoEncoderSoftwareFallbackWrapperTest, TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
SupportsNativeHandleForwardedWithoutFallback) { SupportsNativeHandleForwardedWithoutFallback) {
fallback_wrapper_.SupportsNativeHandle(); fallback_wrapper_->SupportsNativeHandle();
EXPECT_EQ(1, fake_encoder_->supports_native_handle_count_); EXPECT_EQ(1, fake_encoder_->supports_native_handle_count_);
} }
TEST_F(VideoEncoderSoftwareFallbackWrapperTest, TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
SupportsNativeHandleNotForwardedDuringFallback) { SupportsNativeHandleNotForwardedDuringFallback) {
UtilizeFallbackEncoder(); UtilizeFallbackEncoder();
fallback_wrapper_.SupportsNativeHandle(); fallback_wrapper_->SupportsNativeHandle();
EXPECT_EQ(0, fake_encoder_->supports_native_handle_count_); EXPECT_EQ(0, fake_encoder_->supports_native_handle_count_);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
} }
TEST_F(VideoEncoderSoftwareFallbackWrapperTest, ReportsImplementationName) { TEST_F(VideoEncoderSoftwareFallbackWrapperTest, ReportsImplementationName) {
codec_.width = kWidth; codec_.width = kWidth;
codec_.height = kHeight; codec_.height = kHeight;
fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
fallback_wrapper_.InitEncode(&codec_, kNumCores, kMaxPayloadSize); fallback_wrapper_->InitEncode(&codec_, kNumCores, kMaxPayloadSize);
EncodeFrame(); EncodeFrame();
CheckLastEncoderName("fake-encoder"); CheckLastEncoderName("fake-encoder");
} }
@ -341,11 +340,11 @@ class ForcedFallbackTest : public VideoEncoderSoftwareFallbackWrapperTest {
} }
void TearDown() override { void TearDown() override {
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
} }
void ConfigureVp8Codec() { void ConfigureVp8Codec() {
fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
codec_.codecType = kVideoCodecVP8; codec_.codecType = kVideoCodecVP8;
codec_.maxFramerate = kFramerate; codec_.maxFramerate = kFramerate;
codec_.width = kWidth; codec_.width = kWidth;
@ -359,13 +358,13 @@ class ForcedFallbackTest : public VideoEncoderSoftwareFallbackWrapperTest {
void InitEncode(int width, int height) { void InitEncode(int width, int height) {
codec_.width = width; codec_.width = width;
codec_.height = height; codec_.height = height;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.InitEncode( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->InitEncode(
&codec_, kNumCores, kMaxPayloadSize)); &codec_, kNumCores, kMaxPayloadSize));
SetRateAllocation(kBitrateKbps); SetRateAllocation(kBitrateKbps);
} }
void SetRateAllocation(uint32_t bitrate_kbps) { void SetRateAllocation(uint32_t bitrate_kbps) {
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.SetRateAllocation( EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->SetRateAllocation(
rate_allocator_->GetAllocation( rate_allocator_->GetAllocation(
bitrate_kbps * 1000, kFramerate), bitrate_kbps * 1000, kFramerate),
kFramerate)); kFramerate));
@ -490,7 +489,7 @@ TEST_F(ForcedFallbackTestDisabled, GetScaleSettings) {
EncodeFrameAndVerifyLastName("fake-encoder"); EncodeFrameAndVerifyLastName("fake-encoder");
// Default min pixels per frame should be used. // Default min pixels per frame should be used.
const auto settings = fallback_wrapper_.GetScalingSettings(); const auto settings = fallback_wrapper_->GetScalingSettings();
EXPECT_TRUE(settings.thresholds.has_value()); EXPECT_TRUE(settings.thresholds.has_value());
EXPECT_EQ(kDefaultMinPixelsPerFrame, settings.min_pixels_per_frame); EXPECT_EQ(kDefaultMinPixelsPerFrame, settings.min_pixels_per_frame);
} }
@ -501,7 +500,7 @@ TEST_F(ForcedFallbackTestEnabled, GetScaleSettingsWithNoFallback) {
EncodeFrameAndVerifyLastName("fake-encoder"); EncodeFrameAndVerifyLastName("fake-encoder");
// Configured min pixels per frame should be used. // Configured min pixels per frame should be used.
const auto settings = fallback_wrapper_.GetScalingSettings(); const auto settings = fallback_wrapper_->GetScalingSettings();
EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame); EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame);
ASSERT_TRUE(settings.thresholds); ASSERT_TRUE(settings.thresholds);
EXPECT_EQ(kLowThreshold, settings.thresholds->low); EXPECT_EQ(kLowThreshold, settings.thresholds->low);
@ -514,7 +513,7 @@ TEST_F(ForcedFallbackTestEnabled, GetScaleSettingsWithFallback) {
EncodeFrameAndVerifyLastName("libvpx"); EncodeFrameAndVerifyLastName("libvpx");
// Configured min pixels per frame should be used. // Configured min pixels per frame should be used.
const auto settings = fallback_wrapper_.GetScalingSettings(); const auto settings = fallback_wrapper_->GetScalingSettings();
EXPECT_TRUE(settings.thresholds.has_value()); EXPECT_TRUE(settings.thresholds.has_value());
EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame); EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame);
} }
@ -526,7 +525,7 @@ TEST_F(ForcedFallbackTestEnabled, ScalingDisabledIfResizeOff) {
EncodeFrameAndVerifyLastName("libvpx"); EncodeFrameAndVerifyLastName("libvpx");
// Should be disabled for automatic resize off. // Should be disabled for automatic resize off.
const auto settings = fallback_wrapper_.GetScalingSettings(); const auto settings = fallback_wrapper_->GetScalingSettings();
EXPECT_FALSE(settings.thresholds.has_value()); EXPECT_FALSE(settings.thresholds.has_value());
} }

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "media/engine/videodecodersoftwarefallbackwrapper.h" #include "api/video_codecs/video_decoder_software_fallback_wrapper.h"
#include <string> #include <string>
#include <utility> #include <utility>
@ -16,11 +16,58 @@
#include "modules/video_coding/include/video_error_codes.h" #include "modules/video_coding/include/video_error_codes.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "rtc_base/ptr_util.h"
#include "rtc_base/system/fallthrough.h" #include "rtc_base/system/fallthrough.h"
#include "rtc_base/trace_event.h" #include "rtc_base/trace_event.h"
namespace webrtc { namespace webrtc {
namespace {
class VideoDecoderSoftwareFallbackWrapper final : public VideoDecoder {
public:
VideoDecoderSoftwareFallbackWrapper(
std::unique_ptr<VideoDecoder> sw_fallback_decoder,
std::unique_ptr<VideoDecoder> hw_decoder);
~VideoDecoderSoftwareFallbackWrapper() override;
int32_t InitDecode(const VideoCodec* codec_settings,
int32_t number_of_cores) override;
int32_t Decode(const EncodedImage& input_image,
bool missing_frames,
const CodecSpecificInfo* codec_specific_info,
int64_t render_time_ms) override;
int32_t RegisterDecodeCompleteCallback(
DecodedImageCallback* callback) override;
int32_t Release() override;
bool PrefersLateDecoding() const override;
const char* ImplementationName() const override;
private:
bool InitFallbackDecoder();
int32_t InitHwDecoder();
VideoDecoder& active_decoder() const;
// Determines if we are trying to use the HW or SW decoder.
enum class DecoderType {
kNone,
kHardware,
kFallback,
} decoder_type_;
std::unique_ptr<VideoDecoder> hw_decoder_;
VideoCodec codec_settings_;
int32_t number_of_cores_;
const std::unique_ptr<VideoDecoder> fallback_decoder_;
const std::string fallback_implementation_name_;
DecodedImageCallback* callback_;
};
VideoDecoderSoftwareFallbackWrapper::VideoDecoderSoftwareFallbackWrapper( VideoDecoderSoftwareFallbackWrapper::VideoDecoderSoftwareFallbackWrapper(
std::unique_ptr<VideoDecoder> sw_fallback_decoder, std::unique_ptr<VideoDecoder> sw_fallback_decoder,
std::unique_ptr<VideoDecoder> hw_decoder) std::unique_ptr<VideoDecoder> hw_decoder)
@ -115,8 +162,7 @@ int32_t VideoDecoderSoftwareFallbackWrapper::Decode(
} }
case DecoderType::kFallback: case DecoderType::kFallback:
return fallback_decoder_->Decode(input_image, missing_frames, return fallback_decoder_->Decode(input_image, missing_frames,
codec_specific_info, codec_specific_info, render_time_ms);
render_time_ms);
default: default:
RTC_NOTREACHED(); RTC_NOTREACHED();
return WEBRTC_VIDEO_CODEC_ERROR; return WEBRTC_VIDEO_CODEC_ERROR;
@ -166,4 +212,13 @@ VideoDecoder& VideoDecoderSoftwareFallbackWrapper::active_decoder() const {
: *hw_decoder_; : *hw_decoder_;
} }
} // namespace
std::unique_ptr<VideoDecoder> CreateVideoDecoderSoftwareFallbackWrapper(
std::unique_ptr<VideoDecoder> sw_fallback_decoder,
std::unique_ptr<VideoDecoder> hw_decoder) {
return rtc::MakeUnique<VideoDecoderSoftwareFallbackWrapper>(
std::move(sw_fallback_decoder), std::move(hw_decoder));
}
} // namespace webrtc } // namespace webrtc

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef API_VIDEO_CODECS_VIDEO_DECODER_SOFTWARE_FALLBACK_WRAPPER_H_
#define API_VIDEO_CODECS_VIDEO_DECODER_SOFTWARE_FALLBACK_WRAPPER_H_
#include <memory>
#include "api/video_codecs/video_decoder.h"
namespace webrtc {
// Used to wrap external VideoDecoders to provide a fallback option on
// software decoding when a hardware decoder fails to decode a stream due to
// hardware restrictions, such as max resolution.
std::unique_ptr<VideoDecoder> CreateVideoDecoderSoftwareFallbackWrapper(
std::unique_ptr<VideoDecoder> sw_fallback_decoder,
std::unique_ptr<VideoDecoder> hw_decoder);
} // namespace webrtc
#endif // API_VIDEO_CODECS_VIDEO_DECODER_SOFTWARE_FALLBACK_WRAPPER_H_

View File

@ -8,20 +8,26 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "media/engine/videoencodersoftwarefallbackwrapper.h" #include "api/video_codecs/video_encoder_software_fallback_wrapper.h"
#include <cstdio> #include <cstdio>
#include <string>
#include <utility> #include <utility>
#include <vector>
#include "media/base/codec.h"
#include "media/base/h264_profile_level_id.h" #include "media/base/h264_profile_level_id.h"
#include "modules/video_coding/include/video_error_codes.h" #include "modules/video_coding/include/video_error_codes.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "rtc_base/ptr_util.h"
#include "rtc_base/timeutils.h" #include "rtc_base/timeutils.h"
#include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/field_trial.h"
namespace webrtc { namespace webrtc {
namespace { namespace {
const char kVp8ForceFallbackEncoderFieldTrial[] = const char kVp8ForceFallbackEncoderFieldTrial[] =
"WebRTC-VP8-Forced-Fallback-Encoder-v2"; "WebRTC-VP8-Forced-Fallback-Encoder-v2";
@ -62,7 +68,81 @@ void GetForcedFallbackParamsFromFieldTrialGroup(int* param_min_pixels,
*param_min_pixels = min_pixels; *param_min_pixels = min_pixels;
*param_max_pixels = max_pixels; *param_max_pixels = max_pixels;
} }
} // namespace
class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder {
public:
VideoEncoderSoftwareFallbackWrapper(
std::unique_ptr<webrtc::VideoEncoder> sw_encoder,
std::unique_ptr<webrtc::VideoEncoder> hw_encoder);
~VideoEncoderSoftwareFallbackWrapper() override;
int32_t InitEncode(const VideoCodec* codec_settings,
int32_t number_of_cores,
size_t max_payload_size) override;
int32_t RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) override;
int32_t Release() override;
int32_t Encode(const VideoFrame& frame,
const CodecSpecificInfo* codec_specific_info,
const std::vector<FrameType>* frame_types) override;
int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) override;
int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
uint32_t framerate) override;
bool SupportsNativeHandle() const override;
ScalingSettings GetScalingSettings() const override;
const char* ImplementationName() const override;
private:
bool InitFallbackEncoder();
// If |forced_fallback_possible_| is true:
// The forced fallback is requested if the resolution is less than or equal to
// |max_pixels_|. The resolution is allowed to be scaled down to
// |min_pixels_|.
class ForcedFallbackParams {
public:
bool IsValid(const VideoCodec& codec) const {
return codec.width * codec.height <= max_pixels_;
}
bool active_ = false;
int min_pixels_ = 320 * 180;
int max_pixels_ = 320 * 240;
};
bool TryInitForcedFallbackEncoder();
bool TryReInitForcedFallbackEncoder();
void ValidateSettingsForForcedFallback();
bool IsForcedFallbackActive() const;
void MaybeModifyCodecForFallback();
// Settings used in the last InitEncode call and used if a dynamic fallback to
// software is required.
VideoCodec codec_settings_;
int32_t number_of_cores_;
size_t max_payload_size_;
// The last bitrate/framerate set, and a flag for noting they are set.
bool rates_set_;
VideoBitrateAllocation bitrate_allocation_;
uint32_t framerate_;
// The last channel parameters set, and a flag for noting they are set.
bool channel_parameters_set_;
uint32_t packet_loss_;
int64_t rtt_;
bool use_fallback_encoder_;
const std::unique_ptr<webrtc::VideoEncoder> encoder_;
const std::unique_ptr<webrtc::VideoEncoder> fallback_encoder_;
EncodedImageCallback* callback_;
bool forced_fallback_possible_;
ForcedFallbackParams forced_fallback_;
};
VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper( VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper(
std::unique_ptr<webrtc::VideoEncoder> sw_encoder, std::unique_ptr<webrtc::VideoEncoder> sw_encoder,
@ -295,4 +375,13 @@ void VideoEncoderSoftwareFallbackWrapper::ValidateSettingsForForcedFallback() {
} }
} }
} // namespace
std::unique_ptr<VideoEncoder> CreateVideoEncoderSoftwareFallbackWrapper(
std::unique_ptr<VideoEncoder> sw_fallback_encoder,
std::unique_ptr<VideoEncoder> hw_encoder) {
return rtc::MakeUnique<VideoEncoderSoftwareFallbackWrapper>(
std::move(sw_fallback_encoder), std::move(hw_encoder));
}
} // namespace webrtc } // namespace webrtc

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef API_VIDEO_CODECS_VIDEO_ENCODER_SOFTWARE_FALLBACK_WRAPPER_H_
#define API_VIDEO_CODECS_VIDEO_ENCODER_SOFTWARE_FALLBACK_WRAPPER_H_
#include <memory>
#include "api/video_codecs/video_encoder.h"
namespace webrtc {
// Used to wrap external VideoEncoders to provide a fallback option on
// software encoding when a hardware encoder fails to encode a stream due to
// hardware restrictions, such as max resolution.
std::unique_ptr<VideoEncoder> CreateVideoEncoderSoftwareFallbackWrapper(
std::unique_ptr<VideoEncoder> sw_fallback_encoder,
std::unique_ptr<VideoEncoder> hw_encoder);
} // namespace webrtc
#endif // API_VIDEO_CODECS_VIDEO_ENCODER_SOFTWARE_FALLBACK_WRAPPER_H_

View File

@ -192,10 +192,10 @@ rtc_static_library("rtc_internal_video_codecs") {
deps += [ deps += [
":rtc_constants", ":rtc_constants",
":rtc_media_base", ":rtc_media_base",
":rtc_software_fallback_wrappers",
"..:webrtc_common", "..:webrtc_common",
"../api/video:video_bitrate_allocation", "../api/video:video_bitrate_allocation",
"../api/video:video_frame_i420", "../api/video:video_frame_i420",
"../api/video_codecs:rtc_software_fallback_wrappers",
"../api/video_codecs:video_codecs_api", "../api/video_codecs:video_codecs_api",
"../call:call_interfaces", "../call:call_interfaces",
"../call:video_stream_api", "../call:video_stream_api",
@ -214,32 +214,6 @@ rtc_static_library("rtc_internal_video_codecs") {
] ]
} }
rtc_static_library("rtc_software_fallback_wrappers") {
sources = [
"engine/videodecodersoftwarefallbackwrapper.cc",
"engine/videodecodersoftwarefallbackwrapper.h",
"engine/videoencodersoftwarefallbackwrapper.cc",
"engine/videoencodersoftwarefallbackwrapper.h",
]
if (!build_with_chromium && is_clang) {
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
}
deps = [
":rtc_h264_profile_id",
":rtc_media_base",
"../api/video:video_bitrate_allocation",
"../api/video_codecs:video_codecs_api",
"../modules/video_coding:video_codec_interface",
"../rtc_base:checks",
"../rtc_base:rtc_base_approved",
"../rtc_base/system:fallthrough",
"../system_wrappers:field_trial_api",
]
}
rtc_static_library("rtc_audio_video") { rtc_static_library("rtc_audio_video") {
visibility = [ "*" ] visibility = [ "*" ]
allow_poison = [ allow_poison = [
@ -327,7 +301,6 @@ rtc_static_library("rtc_audio_video") {
deps += [ deps += [
":rtc_constants", ":rtc_constants",
":rtc_media_base", ":rtc_media_base",
":rtc_software_fallback_wrappers",
"..:webrtc_common", "..:webrtc_common",
"../api:call_api", "../api:call_api",
"../api:libjingle_peerconnection_api", "../api:libjingle_peerconnection_api",
@ -336,6 +309,7 @@ rtc_static_library("rtc_audio_video") {
"../api/audio_codecs:audio_codecs_api", "../api/audio_codecs:audio_codecs_api",
"../api/video:video_frame", "../api/video:video_frame",
"../api/video:video_frame_i420", "../api/video:video_frame_i420",
"../api/video_codecs:rtc_software_fallback_wrappers",
"../api/video_codecs:video_codecs_api", "../api/video_codecs:video_codecs_api",
"../call", "../call",
"../call:call_interfaces", "../call:call_interfaces",
@ -547,8 +521,6 @@ if (rtc_include_tests) {
"engine/nullwebrtcvideoengine_unittest.cc", "engine/nullwebrtcvideoengine_unittest.cc",
"engine/payload_type_mapper_unittest.cc", "engine/payload_type_mapper_unittest.cc",
"engine/simulcast_encoder_adapter_unittest.cc", "engine/simulcast_encoder_adapter_unittest.cc",
"engine/videodecodersoftwarefallbackwrapper_unittest.cc",
"engine/videoencodersoftwarefallbackwrapper_unittest.cc",
"engine/vp8_encoder_simulcast_proxy_unittest.cc", "engine/vp8_encoder_simulcast_proxy_unittest.cc",
"engine/webrtcmediaengine_unittest.cc", "engine/webrtcmediaengine_unittest.cc",
"engine/webrtcvideocapturer_unittest.cc", "engine/webrtcvideocapturer_unittest.cc",
@ -608,7 +580,6 @@ if (rtc_include_tests) {
":rtc_media", ":rtc_media",
":rtc_media_base", ":rtc_media_base",
":rtc_media_tests_utils", ":rtc_media_tests_utils",
":rtc_software_fallback_wrappers",
"../api:create_simulcast_test_fixture_api", "../api:create_simulcast_test_fixture_api",
"../api:libjingle_peerconnection_api", "../api:libjingle_peerconnection_api",
"../api:mock_video_codec_factory", "../api:mock_video_codec_factory",

View File

@ -14,15 +14,15 @@
#include <vector> #include <vector>
#include "api/video_codecs/video_decoder_factory.h" #include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_decoder_software_fallback_wrapper.h"
#include "api/video_codecs/video_encoder_factory.h" #include "api/video_codecs/video_encoder_factory.h"
#include "api/video_codecs/video_encoder_software_fallback_wrapper.h"
#include "media/base/h264_profile_level_id.h" #include "media/base/h264_profile_level_id.h"
#include "media/engine/internaldecoderfactory.h" #include "media/engine/internaldecoderfactory.h"
#include "media/engine/internalencoderfactory.h" #include "media/engine/internalencoderfactory.h"
#include "media/engine/scopedvideodecoder.h" #include "media/engine/scopedvideodecoder.h"
#include "media/engine/scopedvideoencoder.h" #include "media/engine/scopedvideoencoder.h"
#include "media/engine/simulcast_encoder_adapter.h" #include "media/engine/simulcast_encoder_adapter.h"
#include "media/engine/videodecodersoftwarefallbackwrapper.h"
#include "media/engine/videoencodersoftwarefallbackwrapper.h"
#include "media/engine/vp8_encoder_simulcast_proxy.h" #include "media/engine/vp8_encoder_simulcast_proxy.h"
#include "media/engine/webrtcvideodecoderfactory.h" #include "media/engine/webrtcvideodecoderfactory.h"
#include "media/engine/webrtcvideoencoderfactory.h" #include "media/engine/webrtcvideoencoderfactory.h"
@ -144,7 +144,7 @@ class EncoderAdapter : public webrtc::VideoEncoderFactory {
if (internal_encoder && external_encoder) { if (internal_encoder && external_encoder) {
// Both internal SW encoder and external HW encoder available - create // Both internal SW encoder and external HW encoder available - create
// fallback encoder. // fallback encoder.
return rtc::MakeUnique<webrtc::VideoEncoderSoftwareFallbackWrapper>( return webrtc::CreateVideoEncoderSoftwareFallbackWrapper(
std::move(internal_encoder), std::move(external_encoder)); std::move(internal_encoder), std::move(external_encoder));
} }
return external_encoder ? std::move(external_encoder) return external_encoder ? std::move(external_encoder)
@ -199,9 +199,8 @@ class DecoderAdapter : public webrtc::VideoDecoderFactory {
return external_decoder; return external_decoder;
// Both external and internal decoder available - create fallback // Both external and internal decoder available - create fallback
// wrapper. // wrapper.
return std::unique_ptr<webrtc::VideoDecoder>( return webrtc::CreateVideoDecoderSoftwareFallbackWrapper(
new webrtc::VideoDecoderSoftwareFallbackWrapper( std::move(internal_decoder), std::move(external_decoder));
std::move(internal_decoder), std::move(external_decoder)));
} }
} }

View File

@ -1,70 +0,0 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MEDIA_ENGINE_VIDEODECODERSOFTWAREFALLBACKWRAPPER_H_
#define MEDIA_ENGINE_VIDEODECODERSOFTWAREFALLBACKWRAPPER_H_
#include <memory>
#include <string>
#include "api/video_codecs/video_decoder.h"
namespace webrtc {
// Class used to wrap external VideoDecoders to provide a fallback option on
// software decoding when a hardware decoder fails to decode a stream due to
// hardware restrictions, such as max resolution.
class VideoDecoderSoftwareFallbackWrapper : public VideoDecoder {
public:
VideoDecoderSoftwareFallbackWrapper(
std::unique_ptr<VideoDecoder> sw_fallback_decoder,
std::unique_ptr<VideoDecoder> hw_decoder);
~VideoDecoderSoftwareFallbackWrapper() override;
int32_t InitDecode(const VideoCodec* codec_settings,
int32_t number_of_cores) override;
int32_t Decode(const EncodedImage& input_image,
bool missing_frames,
const CodecSpecificInfo* codec_specific_info,
int64_t render_time_ms) override;
int32_t RegisterDecodeCompleteCallback(
DecodedImageCallback* callback) override;
int32_t Release() override;
bool PrefersLateDecoding() const override;
const char* ImplementationName() const override;
private:
bool InitFallbackDecoder();
int32_t InitHwDecoder();
VideoDecoder& active_decoder() const;
// Determines if we are trying to use the HW or SW decoder.
enum class DecoderType {
kNone,
kHardware,
kFallback,
} decoder_type_;
std::unique_ptr<VideoDecoder> hw_decoder_;
VideoCodec codec_settings_;
int32_t number_of_cores_;
const std::unique_ptr<VideoDecoder> fallback_decoder_;
const std::string fallback_implementation_name_;
DecodedImageCallback* callback_;
};
} // namespace webrtc
#endif // MEDIA_ENGINE_VIDEODECODERSOFTWAREFALLBACKWRAPPER_H_

View File

@ -1,103 +0,0 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MEDIA_ENGINE_VIDEOENCODERSOFTWAREFALLBACKWRAPPER_H_
#define MEDIA_ENGINE_VIDEOENCODERSOFTWAREFALLBACKWRAPPER_H_
#include <memory>
#include <string>
#include <vector>
#include "api/video_codecs/video_encoder.h"
#include "media/base/codec.h"
namespace webrtc {
// Class used to wrap external VideoEncoders to provide a fallback option on
// software encoding when a hardware encoder fails to encode a stream due to
// hardware restrictions, such as max resolution.
class VideoEncoderSoftwareFallbackWrapper : public VideoEncoder {
public:
VideoEncoderSoftwareFallbackWrapper(
std::unique_ptr<webrtc::VideoEncoder> sw_encoder,
std::unique_ptr<webrtc::VideoEncoder> hw_encoder);
~VideoEncoderSoftwareFallbackWrapper() override;
int32_t InitEncode(const VideoCodec* codec_settings,
int32_t number_of_cores,
size_t max_payload_size) override;
int32_t RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) override;
int32_t Release() override;
int32_t Encode(const VideoFrame& frame,
const CodecSpecificInfo* codec_specific_info,
const std::vector<FrameType>* frame_types) override;
int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) override;
int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
uint32_t framerate) override;
bool SupportsNativeHandle() const override;
ScalingSettings GetScalingSettings() const override;
const char *ImplementationName() const override;
private:
bool InitFallbackEncoder();
// If |forced_fallback_possible_| is true:
// The forced fallback is requested if the resolution is less than or equal to
// |max_pixels_|. The resolution is allowed to be scaled down to
// |min_pixels_|.
class ForcedFallbackParams {
public:
bool IsValid(const VideoCodec& codec) const {
return codec.width * codec.height <= max_pixels_;
}
bool active_ = false;
int min_pixels_ = 320 * 180;
int max_pixels_ = 320 * 240;
};
bool TryInitForcedFallbackEncoder();
bool TryReInitForcedFallbackEncoder();
void ValidateSettingsForForcedFallback();
bool IsForcedFallbackActive() const;
void MaybeModifyCodecForFallback();
// Settings used in the last InitEncode call and used if a dynamic fallback to
// software is required.
VideoCodec codec_settings_;
int32_t number_of_cores_;
size_t max_payload_size_;
// The last bitrate/framerate set, and a flag for noting they are set.
bool rates_set_;
VideoBitrateAllocation bitrate_allocation_;
uint32_t framerate_;
// The last channel parameters set, and a flag for noting they are set.
bool channel_parameters_set_;
uint32_t packet_loss_;
int64_t rtt_;
bool use_fallback_encoder_;
const std::unique_ptr<webrtc::VideoEncoder> encoder_;
const std::unique_ptr<webrtc::VideoEncoder> fallback_encoder_;
EncodedImageCallback* callback_;
bool forced_fallback_possible_;
ForcedFallbackParams forced_fallback_;
};
} // namespace webrtc
#endif // MEDIA_ENGINE_VIDEOENCODERSOFTWAREFALLBACKWRAPPER_H_

View File

@ -726,12 +726,12 @@ if (rtc_include_tests) {
"../../api:optional", "../../api:optional",
"../../api:videocodec_test_fixture_api", "../../api:videocodec_test_fixture_api",
"../../api/video:video_frame_i420", "../../api/video:video_frame_i420",
"../../api/video_codecs:rtc_software_fallback_wrappers",
"../../api/video_codecs:video_codecs_api", "../../api/video_codecs:video_codecs_api",
"../../common_video", "../../common_video",
"../../media:rtc_h264_profile_id", "../../media:rtc_h264_profile_id",
"../../media:rtc_internal_video_codecs", "../../media:rtc_internal_video_codecs",
"../../media:rtc_media_base", "../../media:rtc_media_base",
"../../media:rtc_software_fallback_wrappers",
"../../rtc_base:rtc_base", "../../rtc_base:rtc_base",
"../../test:fileutils", "../../test:fileutils",
"../../test:test_common", "../../test:test_common",

View File

@ -366,12 +366,12 @@ rtc_static_library("video_jni") {
"../..:webrtc_common", "../..:webrtc_common",
"../../api:libjingle_peerconnection_api", "../../api:libjingle_peerconnection_api",
"../../api/video:video_frame", "../../api/video:video_frame",
"../../api/video_codecs:rtc_software_fallback_wrappers",
"../../api/video_codecs:video_codecs_api", "../../api/video_codecs:video_codecs_api",
"../../common_video:common_video", "../../common_video:common_video",
"../../media:rtc_audio_video", "../../media:rtc_audio_video",
"../../media:rtc_h264_profile_id", "../../media:rtc_h264_profile_id",
"../../media:rtc_media_base", "../../media:rtc_media_base",
"../../media:rtc_software_fallback_wrappers",
"../../modules:module_api", "../../modules:module_api",
"../../modules/utility:utility", "../../modules/utility:utility",
"../../modules/video_coding:codec_globals_headers", "../../modules/video_coding:codec_globals_headers",

View File

@ -10,7 +10,7 @@
#include <jni.h> #include <jni.h>
#include "media/engine/videodecodersoftwarefallbackwrapper.h" #include "api/video_codecs/video_decoder_software_fallback_wrapper.h"
#include "sdk/android/generated_video_jni/jni/VideoDecoderFallback_jni.h" #include "sdk/android/generated_video_jni/jni/VideoDecoderFallback_jni.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/wrappednativecodec.h" #include "sdk/android/src/jni/wrappednativecodec.h"
@ -28,9 +28,10 @@ static jlong JNI_VideoDecoderFallback_CreateDecoder(
std::unique_ptr<VideoDecoder> primary_decoder = std::unique_ptr<VideoDecoder> primary_decoder =
JavaToNativeVideoDecoder(jni, j_primary_decoder); JavaToNativeVideoDecoder(jni, j_primary_decoder);
VideoDecoderSoftwareFallbackWrapper* nativeWrapper = VideoDecoder* nativeWrapper =
new VideoDecoderSoftwareFallbackWrapper(std::move(fallback_decoder), CreateVideoDecoderSoftwareFallbackWrapper(std::move(fallback_decoder),
std::move(primary_decoder)); std::move(primary_decoder))
.release();
return jlongFromPointer(nativeWrapper); return jlongFromPointer(nativeWrapper);
} }

View File

@ -10,7 +10,7 @@
#include <jni.h> #include <jni.h>
#include "media/engine/videoencodersoftwarefallbackwrapper.h" #include "api/video_codecs/video_encoder_software_fallback_wrapper.h"
#include "sdk/android/generated_video_jni/jni/VideoEncoderFallback_jni.h" #include "sdk/android/generated_video_jni/jni/VideoEncoderFallback_jni.h"
#include "sdk/android/src/jni/jni_helpers.h" #include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/wrappednativecodec.h" #include "sdk/android/src/jni/wrappednativecodec.h"
@ -28,9 +28,10 @@ static jlong JNI_VideoEncoderFallback_CreateEncoder(
std::unique_ptr<VideoEncoder> primary_encoder = std::unique_ptr<VideoEncoder> primary_encoder =
JavaToNativeVideoEncoder(jni, j_primary_encoder); JavaToNativeVideoEncoder(jni, j_primary_encoder);
VideoEncoderSoftwareFallbackWrapper* nativeWrapper = VideoEncoder* nativeWrapper =
new VideoEncoderSoftwareFallbackWrapper(std::move(fallback_encoder), CreateVideoEncoderSoftwareFallbackWrapper(std::move(fallback_encoder),
std::move(primary_encoder)); std::move(primary_encoder))
.release();
return jlongFromPointer(nativeWrapper); return jlongFromPointer(nativeWrapper);
} }