Inform VideoEncoder of negotiated capabilities
After this CL lands, an announcement will be made to discuss-webrtc about the deprecation of one version of InitEncode(). Bug: webrtc:10720 Change-Id: Ib992af0272bbb16ae16ef7e69491f365702d179e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/140884 Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Reviewed-by: Sami Kalliomäki <sakal@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Elad Alon <eladalon@webrtc.org> Cr-Commit-Position: refs/heads/master@{#28224}
This commit is contained in:
parent
a7d70ab0fe
commit
11dfff0878
@ -37,6 +37,10 @@ class MockVideoEncoder : public VideoEncoder {
|
|||||||
int32_t(const VideoCodec* codecSettings,
|
int32_t(const VideoCodec* codecSettings,
|
||||||
int32_t numberOfCores,
|
int32_t numberOfCores,
|
||||||
size_t maxPayloadSize));
|
size_t maxPayloadSize));
|
||||||
|
MOCK_METHOD2(InitEncode,
|
||||||
|
int32_t(const VideoCodec* codecSettings,
|
||||||
|
const VideoEncoder::Settings& settings));
|
||||||
|
|
||||||
MOCK_METHOD2(Encode,
|
MOCK_METHOD2(Encode,
|
||||||
int32_t(const VideoFrame& inputImage,
|
int32_t(const VideoFrame& inputImage,
|
||||||
const std::vector<VideoFrameType>* frame_types));
|
const std::vector<VideoFrameType>* frame_types));
|
||||||
|
|||||||
@ -12,12 +12,15 @@
|
|||||||
#define API_VIDEO_VIDEO_STREAM_ENCODER_SETTINGS_H_
|
#define API_VIDEO_VIDEO_STREAM_ENCODER_SETTINGS_H_
|
||||||
|
|
||||||
#include "api/video/video_bitrate_allocator_factory.h"
|
#include "api/video/video_bitrate_allocator_factory.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "api/video_codecs/video_encoder_factory.h"
|
#include "api/video_codecs/video_encoder_factory.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
struct VideoStreamEncoderSettings {
|
struct VideoStreamEncoderSettings {
|
||||||
VideoStreamEncoderSettings() = default;
|
explicit VideoStreamEncoderSettings(
|
||||||
|
const VideoEncoder::Capabilities& capabilities)
|
||||||
|
: capabilities(capabilities) {}
|
||||||
|
|
||||||
// Enables the new method to estimate the cpu load from encoding, used for
|
// Enables the new method to estimate the cpu load from encoding, used for
|
||||||
// cpu adaptation.
|
// cpu adaptation.
|
||||||
@ -28,6 +31,10 @@ struct VideoStreamEncoderSettings {
|
|||||||
|
|
||||||
// Ownership stays with WebrtcVideoEngine (delegated from PeerConnection).
|
// Ownership stays with WebrtcVideoEngine (delegated from PeerConnection).
|
||||||
VideoBitrateAllocatorFactory* bitrate_allocator_factory = nullptr;
|
VideoBitrateAllocatorFactory* bitrate_allocator_factory = nullptr;
|
||||||
|
|
||||||
|
// Negotiated capabilities which the VideoEncoder may expect the other
|
||||||
|
// side to use.
|
||||||
|
VideoEncoder::Capabilities capabilities;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -50,6 +50,11 @@ const int kDefaultMinPixelsPerFrame = 320 * 180;
|
|||||||
const int kLowThreshold = 10;
|
const int kLowThreshold = 10;
|
||||||
const int kHighThreshold = 20;
|
const int kHighThreshold = 20;
|
||||||
|
|
||||||
|
const VideoEncoder::Capabilities kCapabilities(false);
|
||||||
|
const VideoEncoder::Settings kSettings(kCapabilities,
|
||||||
|
kNumCores,
|
||||||
|
kMaxPayloadSize);
|
||||||
|
|
||||||
VideoEncoder::EncoderInfo GetEncoderInfoWithTrustedRateController(
|
VideoEncoder::EncoderInfo GetEncoderInfoWithTrustedRateController(
|
||||||
bool trusted_rate_controller) {
|
bool trusted_rate_controller) {
|
||||||
VideoEncoder::EncoderInfo info;
|
VideoEncoder::EncoderInfo info;
|
||||||
@ -89,9 +94,16 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
|
|||||||
int32_t InitEncode(const VideoCodec* codec_settings,
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override {
|
size_t max_payload_size) override {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const VideoEncoder::Settings& settings) override {
|
||||||
++init_encode_count_;
|
++init_encode_count_;
|
||||||
return init_encode_return_code_;
|
return init_encode_return_code_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t Encode(const VideoFrame& frame,
|
int32_t Encode(const VideoFrame& frame,
|
||||||
const std::vector<VideoFrameType>* frame_types) override {
|
const std::vector<VideoFrameType>* frame_types) override {
|
||||||
++encode_count_;
|
++encode_count_;
|
||||||
@ -202,7 +214,7 @@ 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_, kSettings));
|
||||||
fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
|
fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
rate_allocator_->GetAllocation(300000, kFramerate), kFramerate));
|
rate_allocator_->GetAllocation(300000, kFramerate), kFramerate));
|
||||||
|
|
||||||
@ -221,7 +233,7 @@ void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() {
|
|||||||
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_, kSettings);
|
||||||
fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
|
fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
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_);
|
||||||
@ -238,7 +250,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, kSettings);
|
||||||
EXPECT_EQ(1, fake_encoder_->init_encode_count_);
|
EXPECT_EQ(1, fake_encoder_->init_encode_count_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,7 +336,7 @@ 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_, kSettings);
|
||||||
EncodeFrame();
|
EncodeFrame();
|
||||||
CheckLastEncoderName("fake-encoder");
|
CheckLastEncoderName("fake-encoder");
|
||||||
}
|
}
|
||||||
@ -375,8 +387,8 @@ 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,
|
||||||
&codec_, kNumCores, kMaxPayloadSize));
|
fallback_wrapper_->InitEncode(&codec_, kSettings));
|
||||||
SetRateAllocation(kBitrateKbps);
|
SetRateAllocation(kBitrateKbps);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -590,6 +602,9 @@ TEST(SoftwareFallbackEncoderTest, HwRateControllerTrusted) {
|
|||||||
std::unique_ptr<VideoEncoder>(hw_encoder));
|
std::unique_ptr<VideoEncoder>(hw_encoder));
|
||||||
EXPECT_TRUE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
|
EXPECT_TRUE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
|
||||||
|
|
||||||
|
VideoCodec codec_ = {};
|
||||||
|
wrapper->InitEncode(&codec_, kSettings);
|
||||||
|
|
||||||
// Trigger fallback to software.
|
// Trigger fallback to software.
|
||||||
EXPECT_CALL(*hw_encoder, Encode)
|
EXPECT_CALL(*hw_encoder, Encode)
|
||||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
|
.WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
|
||||||
@ -630,6 +645,9 @@ TEST(SoftwareFallbackEncoderTest, ReportsHardwareAccelerated) {
|
|||||||
std::unique_ptr<VideoEncoder>(hw_encoder));
|
std::unique_ptr<VideoEncoder>(hw_encoder));
|
||||||
EXPECT_TRUE(wrapper->GetEncoderInfo().is_hardware_accelerated);
|
EXPECT_TRUE(wrapper->GetEncoderInfo().is_hardware_accelerated);
|
||||||
|
|
||||||
|
VideoCodec codec_ = {};
|
||||||
|
wrapper->InitEncode(&codec_, kSettings);
|
||||||
|
|
||||||
// Trigger fallback to software.
|
// Trigger fallback to software.
|
||||||
EXPECT_CALL(*hw_encoder, Encode)
|
EXPECT_CALL(*hw_encoder, Encode)
|
||||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
|
.WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
|
||||||
@ -654,6 +672,9 @@ TEST(SoftwareFallbackEncoderTest, ReportsInternalSource) {
|
|||||||
std::unique_ptr<VideoEncoder>(hw_encoder));
|
std::unique_ptr<VideoEncoder>(hw_encoder));
|
||||||
EXPECT_TRUE(wrapper->GetEncoderInfo().has_internal_source);
|
EXPECT_TRUE(wrapper->GetEncoderInfo().has_internal_source);
|
||||||
|
|
||||||
|
VideoCodec codec_ = {};
|
||||||
|
wrapper->InitEncode(&codec_, kSettings);
|
||||||
|
|
||||||
// Trigger fallback to software.
|
// Trigger fallback to software.
|
||||||
EXPECT_CALL(*hw_encoder, Encode)
|
EXPECT_CALL(*hw_encoder, Encode)
|
||||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
|
.WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
|
||||||
|
|||||||
@ -118,6 +118,14 @@ VideoEncoder::RateControlParameters::RateControlParameters(
|
|||||||
|
|
||||||
VideoEncoder::RateControlParameters::~RateControlParameters() = default;
|
VideoEncoder::RateControlParameters::~RateControlParameters() = default;
|
||||||
|
|
||||||
|
int VideoEncoder::InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const VideoEncoder::Settings& settings) {
|
||||||
|
// TODO(bugs.webrtc.org/10720): After updating downstream projects and posting
|
||||||
|
// an announcement to discuss-webrtc, remove this.
|
||||||
|
return InitEncode(codec_settings, settings.number_of_cores,
|
||||||
|
settings.max_payload_size);
|
||||||
|
}
|
||||||
|
|
||||||
void VideoEncoder::OnPacketLossRateUpdate(float packet_loss_rate) {}
|
void VideoEncoder::OnPacketLossRateUpdate(float packet_loss_rate) {}
|
||||||
|
|
||||||
void VideoEncoder::OnRttUpdate(int64_t rtt_ms) {}
|
void VideoEncoder::OnRttUpdate(int64_t rtt_ms) {}
|
||||||
|
|||||||
@ -86,6 +86,7 @@ class RTC_EXPORT VideoEncoder {
|
|||||||
int low;
|
int low;
|
||||||
int high;
|
int high;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Quality scaling is enabled if thresholds are provided.
|
// Quality scaling is enabled if thresholds are provided.
|
||||||
struct ScalingSettings {
|
struct ScalingSettings {
|
||||||
private:
|
private:
|
||||||
@ -237,6 +238,27 @@ class RTC_EXPORT VideoEncoder {
|
|||||||
absl::optional<bool> last_received_decodable;
|
absl::optional<bool> last_received_decodable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Negotiated capabilities which the VideoEncoder may expect the other
|
||||||
|
// side to use.
|
||||||
|
struct Capabilities {
|
||||||
|
explicit Capabilities(bool loss_notification)
|
||||||
|
: loss_notification(loss_notification) {}
|
||||||
|
bool loss_notification;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Settings {
|
||||||
|
Settings(const Capabilities& capabilities,
|
||||||
|
int number_of_cores,
|
||||||
|
size_t max_payload_size)
|
||||||
|
: capabilities(capabilities),
|
||||||
|
number_of_cores(number_of_cores),
|
||||||
|
max_payload_size(max_payload_size) {}
|
||||||
|
|
||||||
|
Capabilities capabilities;
|
||||||
|
int number_of_cores;
|
||||||
|
size_t max_payload_size;
|
||||||
|
};
|
||||||
|
|
||||||
static VideoCodecVP8 GetDefaultVp8Settings();
|
static VideoCodecVP8 GetDefaultVp8Settings();
|
||||||
static VideoCodecVP9 GetDefaultVp9Settings();
|
static VideoCodecVP9 GetDefaultVp9Settings();
|
||||||
static VideoCodecH264 GetDefaultH264Settings();
|
static VideoCodecH264 GetDefaultH264Settings();
|
||||||
@ -247,6 +269,8 @@ class RTC_EXPORT VideoEncoder {
|
|||||||
//
|
//
|
||||||
// Input:
|
// Input:
|
||||||
// - codec_settings : Codec settings
|
// - codec_settings : Codec settings
|
||||||
|
// - settings : Settings affecting the encoding itself.
|
||||||
|
// Input for deprecated version:
|
||||||
// - number_of_cores : Number of cores available for the encoder
|
// - number_of_cores : Number of cores available for the encoder
|
||||||
// - max_payload_size : The maximum size each payload is allowed
|
// - max_payload_size : The maximum size each payload is allowed
|
||||||
// to have. Usually MTU - overhead.
|
// to have. Usually MTU - overhead.
|
||||||
@ -257,9 +281,15 @@ class RTC_EXPORT VideoEncoder {
|
|||||||
// WEBRTC_VIDEO_CODEC_ERR_SIZE
|
// WEBRTC_VIDEO_CODEC_ERR_SIZE
|
||||||
// WEBRTC_VIDEO_CODEC_MEMORY
|
// WEBRTC_VIDEO_CODEC_MEMORY
|
||||||
// WEBRTC_VIDEO_CODEC_ERROR
|
// WEBRTC_VIDEO_CODEC_ERROR
|
||||||
virtual int32_t InitEncode(const VideoCodec* codec_settings,
|
// TODO(bugs.webrtc.org/10720): After updating downstream projects and posting
|
||||||
int32_t number_of_cores,
|
// an announcement to discuss-webrtc, remove the three-parameters variant
|
||||||
size_t max_payload_size) = 0;
|
// and make the two-parameters variant pure-virtual.
|
||||||
|
/* RTC_DEPRECATED */ virtual int32_t InitEncode(
|
||||||
|
const VideoCodec* codec_settings,
|
||||||
|
int32_t number_of_cores,
|
||||||
|
size_t max_payload_size) = 0;
|
||||||
|
virtual int InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const VideoEncoder::Settings& settings);
|
||||||
|
|
||||||
// Register an encode complete callback object.
|
// Register an encode complete callback object.
|
||||||
//
|
//
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#include "api/video/video_bitrate_allocation.h"
|
#include "api/video/video_bitrate_allocation.h"
|
||||||
#include "api/video/video_frame.h"
|
#include "api/video/video_frame.h"
|
||||||
#include "api/video_codecs/video_codec.h"
|
#include "api/video_codecs/video_codec.h"
|
||||||
|
#include "api/video_codecs/video_encoder.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"
|
||||||
@ -81,6 +82,8 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder {
|
|||||||
int32_t InitEncode(const VideoCodec* codec_settings,
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override;
|
size_t max_payload_size) override;
|
||||||
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const VideoEncoder::Settings& settings) override;
|
||||||
|
|
||||||
int32_t RegisterEncodeCompleteCallback(
|
int32_t RegisterEncodeCompleteCallback(
|
||||||
EncodedImageCallback* callback) override;
|
EncodedImageCallback* callback) override;
|
||||||
@ -118,8 +121,7 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder {
|
|||||||
// Settings used in the last InitEncode call and used if a dynamic fallback to
|
// Settings used in the last InitEncode call and used if a dynamic fallback to
|
||||||
// software is required.
|
// software is required.
|
||||||
VideoCodec codec_settings_;
|
VideoCodec codec_settings_;
|
||||||
int32_t number_of_cores_;
|
absl::optional<VideoEncoder::Settings> encoder_settings_;
|
||||||
size_t max_payload_size_;
|
|
||||||
|
|
||||||
// The last rate control settings, if set.
|
// The last rate control settings, if set.
|
||||||
absl::optional<RateControlParameters> rate_control_parameters_;
|
absl::optional<RateControlParameters> rate_control_parameters_;
|
||||||
@ -142,9 +144,7 @@ class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder {
|
|||||||
VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper(
|
VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper(
|
||||||
std::unique_ptr<webrtc::VideoEncoder> sw_encoder,
|
std::unique_ptr<webrtc::VideoEncoder> sw_encoder,
|
||||||
std::unique_ptr<webrtc::VideoEncoder> hw_encoder)
|
std::unique_ptr<webrtc::VideoEncoder> hw_encoder)
|
||||||
: number_of_cores_(0),
|
: channel_parameters_set_(false),
|
||||||
max_payload_size_(0),
|
|
||||||
channel_parameters_set_(false),
|
|
||||||
packet_loss_(0),
|
packet_loss_(0),
|
||||||
rtt_(0),
|
rtt_(0),
|
||||||
use_fallback_encoder_(false),
|
use_fallback_encoder_(false),
|
||||||
@ -165,8 +165,9 @@ VideoEncoderSoftwareFallbackWrapper::~VideoEncoderSoftwareFallbackWrapper() =
|
|||||||
bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder() {
|
bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder() {
|
||||||
RTC_LOG(LS_WARNING) << "Encoder falling back to software encoding.";
|
RTC_LOG(LS_WARNING) << "Encoder falling back to software encoding.";
|
||||||
|
|
||||||
const int ret = fallback_encoder_->InitEncode(
|
RTC_DCHECK(encoder_settings_.has_value());
|
||||||
&codec_settings_, number_of_cores_, max_payload_size_);
|
const int ret = fallback_encoder_->InitEncode(&codec_settings_,
|
||||||
|
encoder_settings_.value());
|
||||||
use_fallback_encoder_ = (ret == WEBRTC_VIDEO_CODEC_OK);
|
use_fallback_encoder_ = (ret == WEBRTC_VIDEO_CODEC_OK);
|
||||||
if (!use_fallback_encoder_) {
|
if (!use_fallback_encoder_) {
|
||||||
RTC_LOG(LS_ERROR) << "Failed to initialize software-encoder fallback.";
|
RTC_LOG(LS_ERROR) << "Failed to initialize software-encoder fallback.";
|
||||||
@ -190,11 +191,17 @@ int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode(
|
|||||||
const VideoCodec* codec_settings,
|
const VideoCodec* codec_settings,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) {
|
size_t max_payload_size) {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode(
|
||||||
|
const VideoCodec* codec_settings,
|
||||||
|
const VideoEncoder::Settings& settings) {
|
||||||
// Store settings, in case we need to dynamically switch to the fallback
|
// Store settings, in case we need to dynamically switch to the fallback
|
||||||
// encoder after a failed Encode call.
|
// encoder after a failed Encode call.
|
||||||
codec_settings_ = *codec_settings;
|
codec_settings_ = *codec_settings;
|
||||||
number_of_cores_ = number_of_cores;
|
encoder_settings_ = settings;
|
||||||
max_payload_size_ = max_payload_size;
|
|
||||||
// Clear stored rate/channel parameters.
|
// Clear stored rate/channel parameters.
|
||||||
rate_control_parameters_ = absl::nullopt;
|
rate_control_parameters_ = absl::nullopt;
|
||||||
ValidateSettingsForForcedFallback();
|
ValidateSettingsForForcedFallback();
|
||||||
@ -209,8 +216,7 @@ int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode(
|
|||||||
}
|
}
|
||||||
forced_fallback_.active_ = false;
|
forced_fallback_.active_ = false;
|
||||||
|
|
||||||
int32_t ret =
|
int32_t ret = encoder_->InitEncode(codec_settings, settings);
|
||||||
encoder_->InitEncode(codec_settings, number_of_cores, max_payload_size);
|
|
||||||
if (ret == WEBRTC_VIDEO_CODEC_OK) {
|
if (ret == WEBRTC_VIDEO_CODEC_OK) {
|
||||||
if (use_fallback_encoder_) {
|
if (use_fallback_encoder_) {
|
||||||
RTC_LOG(LS_WARNING)
|
RTC_LOG(LS_WARNING)
|
||||||
@ -319,14 +325,17 @@ bool VideoEncoderSoftwareFallbackWrapper::TryReInitForcedFallbackEncoder() {
|
|||||||
if (!IsForcedFallbackActive()) {
|
if (!IsForcedFallbackActive()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forced fallback active.
|
// Forced fallback active.
|
||||||
if (!forced_fallback_.IsValid(codec_settings_)) {
|
if (!forced_fallback_.IsValid(codec_settings_)) {
|
||||||
RTC_LOG(LS_INFO) << "Stop forced SW encoder fallback, max pixels exceeded.";
|
RTC_LOG(LS_INFO) << "Stop forced SW encoder fallback, max pixels exceeded.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Settings valid, reinitialize the forced fallback encoder.
|
// Settings valid, reinitialize the forced fallback encoder.
|
||||||
if (fallback_encoder_->InitEncode(&codec_settings_, number_of_cores_,
|
RTC_DCHECK(encoder_settings_.has_value());
|
||||||
max_payload_size_) !=
|
if (fallback_encoder_->InitEncode(&codec_settings_,
|
||||||
|
encoder_settings_.value()) !=
|
||||||
WEBRTC_VIDEO_CODEC_OK) {
|
WEBRTC_VIDEO_CODEC_OK) {
|
||||||
RTC_LOG(LS_ERROR) << "Failed to init forced SW encoder fallback.";
|
RTC_LOG(LS_ERROR) << "Failed to init forced SW encoder fallback.";
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
#include "api/test/simulated_network.h"
|
#include "api/test/simulated_network.h"
|
||||||
#include "api/video/builtin_video_bitrate_allocator_factory.h"
|
#include "api/video/builtin_video_bitrate_allocator_factory.h"
|
||||||
#include "api/video/video_bitrate_allocation.h"
|
#include "api/video/video_bitrate_allocation.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "api/video_codecs/video_encoder_config.h"
|
#include "api/video_codecs/video_encoder_config.h"
|
||||||
#include "call/call.h"
|
#include "call/call.h"
|
||||||
#include "call/fake_network_pipe.h"
|
#include "call/fake_network_pipe.h"
|
||||||
@ -751,6 +752,12 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) {
|
|||||||
int32_t InitEncode(const VideoCodec* config,
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override {
|
size_t max_payload_size) override {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
|
const VideoEncoder::Settings& settings) override {
|
||||||
++encoder_inits_;
|
++encoder_inits_;
|
||||||
if (encoder_inits_ == 1) {
|
if (encoder_inits_ == 1) {
|
||||||
// First time initialization. Frame size is known.
|
// First time initialization. Frame size is known.
|
||||||
@ -771,7 +778,7 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) {
|
|||||||
<< "Encoder reconfigured with bitrate too far away from last set.";
|
<< "Encoder reconfigured with bitrate too far away from last set.";
|
||||||
observation_complete_.Set();
|
observation_complete_.Set();
|
||||||
}
|
}
|
||||||
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
|
return FakeEncoder::InitEncode(config, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetRates(const RateControlParameters& parameters) override {
|
void SetRates(const RateControlParameters& parameters) override {
|
||||||
|
|||||||
@ -77,7 +77,10 @@ VideoSendStream::Config::Config(const Config&) = default;
|
|||||||
VideoSendStream::Config::Config(Config&&) = default;
|
VideoSendStream::Config::Config(Config&&) = default;
|
||||||
VideoSendStream::Config::Config(Transport* send_transport,
|
VideoSendStream::Config::Config(Transport* send_transport,
|
||||||
MediaTransportInterface* media_transport)
|
MediaTransportInterface* media_transport)
|
||||||
: send_transport(send_transport), media_transport(media_transport) {}
|
: rtp(),
|
||||||
|
encoder_settings(VideoEncoder::Capabilities(rtp.lntf.enabled)),
|
||||||
|
send_transport(send_transport),
|
||||||
|
media_transport(media_transport) {}
|
||||||
VideoSendStream::Config::Config(Transport* send_transport)
|
VideoSendStream::Config::Config(Transport* send_transport)
|
||||||
: Config(send_transport, nullptr) {}
|
: Config(send_transport, nullptr) {}
|
||||||
|
|
||||||
|
|||||||
@ -126,10 +126,10 @@ class VideoSendStream {
|
|||||||
|
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
|
|
||||||
VideoStreamEncoderSettings encoder_settings;
|
|
||||||
|
|
||||||
RtpConfig rtp;
|
RtpConfig rtp;
|
||||||
|
|
||||||
|
VideoStreamEncoderSettings encoder_settings;
|
||||||
|
|
||||||
// Time interval between RTCP report for video
|
// Time interval between RTCP report for video
|
||||||
int rtcp_report_interval_ms = 1000;
|
int rtcp_report_interval_ms = 1000;
|
||||||
|
|
||||||
|
|||||||
@ -10,10 +10,12 @@
|
|||||||
|
|
||||||
#include "media/engine/encoder_simulcast_proxy.h"
|
#include "media/engine/encoder_simulcast_proxy.h"
|
||||||
|
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "media/engine/simulcast_encoder_adapter.h"
|
#include "media/engine/simulcast_encoder_adapter.h"
|
||||||
#include "modules/video_coding/include/video_error_codes.h"
|
#include "modules/video_coding/include/video_error_codes.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
EncoderSimulcastProxy::EncoderSimulcastProxy(VideoEncoderFactory* factory,
|
EncoderSimulcastProxy::EncoderSimulcastProxy(VideoEncoderFactory* factory,
|
||||||
const SdpVideoFormat& format)
|
const SdpVideoFormat& format)
|
||||||
: factory_(factory), video_format_(format), callback_(nullptr) {
|
: factory_(factory), video_format_(format), callback_(nullptr) {
|
||||||
@ -32,13 +34,20 @@ int EncoderSimulcastProxy::Release() {
|
|||||||
int EncoderSimulcastProxy::InitEncode(const VideoCodec* inst,
|
int EncoderSimulcastProxy::InitEncode(const VideoCodec* inst,
|
||||||
int number_of_cores,
|
int number_of_cores,
|
||||||
size_t max_payload_size) {
|
size_t max_payload_size) {
|
||||||
int ret = encoder_->InitEncode(inst, number_of_cores, max_payload_size);
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(eladalon): s/inst/codec_settings/g.
|
||||||
|
int EncoderSimulcastProxy::InitEncode(const VideoCodec* inst,
|
||||||
|
const VideoEncoder::Settings& settings) {
|
||||||
|
int ret = encoder_->InitEncode(inst, settings);
|
||||||
if (ret == WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED) {
|
if (ret == WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED) {
|
||||||
encoder_.reset(new SimulcastEncoderAdapter(factory_, video_format_));
|
encoder_.reset(new SimulcastEncoderAdapter(factory_, video_format_));
|
||||||
if (callback_) {
|
if (callback_) {
|
||||||
encoder_->RegisterEncodeCompleteCallback(callback_);
|
encoder_->RegisterEncodeCompleteCallback(callback_);
|
||||||
}
|
}
|
||||||
ret = encoder_->InitEncode(inst, number_of_cores, max_payload_size);
|
ret = encoder_->InitEncode(inst, settings);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,9 +42,11 @@ class RTC_EXPORT EncoderSimulcastProxy : public VideoEncoder {
|
|||||||
|
|
||||||
// Implements VideoEncoder.
|
// Implements VideoEncoder.
|
||||||
int Release() override;
|
int Release() override;
|
||||||
int InitEncode(const VideoCodec* inst,
|
int InitEncode(const VideoCodec* codec_settings,
|
||||||
int number_of_cores,
|
int number_of_cores,
|
||||||
size_t max_payload_size) override;
|
size_t max_payload_size) override;
|
||||||
|
int InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const VideoEncoder::Settings& settings) override;
|
||||||
int Encode(const VideoFrame& input_image,
|
int Encode(const VideoFrame& input_image,
|
||||||
const std::vector<VideoFrameType>* frame_types) override;
|
const std::vector<VideoFrameType>* frame_types) override;
|
||||||
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
|
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "api/test/mock_video_encoder.h"
|
#include "api/test/mock_video_encoder.h"
|
||||||
#include "api/test/mock_video_encoder_factory.h"
|
#include "api/test/mock_video_encoder_factory.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||||
#include "modules/video_coding/include/video_codec_interface.h"
|
#include "modules/video_coding/include/video_codec_interface.h"
|
||||||
#include "test/gmock.h"
|
#include "test/gmock.h"
|
||||||
@ -22,6 +23,10 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
namespace {
|
||||||
|
const VideoEncoder::Capabilities kCapabilities(false);
|
||||||
|
const VideoEncoder::Settings kSettings(kCapabilities, 4, 1200);
|
||||||
|
} // namespace
|
||||||
|
|
||||||
using ::testing::_;
|
using ::testing::_;
|
||||||
using ::testing::NiceMock;
|
using ::testing::NiceMock;
|
||||||
@ -62,7 +67,7 @@ TEST(EncoderSimulcastProxy, ChoosesCorrectImplementation) {
|
|||||||
NiceMock<MockVideoEncoder>* mock_encoder = new NiceMock<MockVideoEncoder>();
|
NiceMock<MockVideoEncoder>* mock_encoder = new NiceMock<MockVideoEncoder>();
|
||||||
NiceMock<MockVideoEncoderFactory> simulcast_factory;
|
NiceMock<MockVideoEncoderFactory> simulcast_factory;
|
||||||
|
|
||||||
EXPECT_CALL(*mock_encoder, InitEncode(_, _, _))
|
EXPECT_CALL(*mock_encoder, InitEncode(_, _))
|
||||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
||||||
VideoEncoder::EncoderInfo encoder_info;
|
VideoEncoder::EncoderInfo encoder_info;
|
||||||
encoder_info.implementation_name = kImplementationName;
|
encoder_info.implementation_name = kImplementationName;
|
||||||
@ -76,7 +81,7 @@ TEST(EncoderSimulcastProxy, ChoosesCorrectImplementation) {
|
|||||||
EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory,
|
EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory,
|
||||||
SdpVideoFormat("VP8"));
|
SdpVideoFormat("VP8"));
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
simulcast_enabled_proxy.InitEncode(&codec_settings, 4, 1200));
|
simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings));
|
||||||
EXPECT_EQ(kImplementationName,
|
EXPECT_EQ(kImplementationName,
|
||||||
simulcast_enabled_proxy.GetEncoderInfo().implementation_name);
|
simulcast_enabled_proxy.GetEncoderInfo().implementation_name);
|
||||||
|
|
||||||
@ -86,23 +91,23 @@ TEST(EncoderSimulcastProxy, ChoosesCorrectImplementation) {
|
|||||||
NiceMock<MockVideoEncoder>* mock_encoder4 = new NiceMock<MockVideoEncoder>();
|
NiceMock<MockVideoEncoder>* mock_encoder4 = new NiceMock<MockVideoEncoder>();
|
||||||
NiceMock<MockVideoEncoderFactory> nonsimulcast_factory;
|
NiceMock<MockVideoEncoderFactory> nonsimulcast_factory;
|
||||||
|
|
||||||
EXPECT_CALL(*mock_encoder1, InitEncode(_, _, _))
|
EXPECT_CALL(*mock_encoder1, InitEncode(_, _))
|
||||||
.WillOnce(
|
.WillOnce(
|
||||||
Return(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED));
|
Return(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED));
|
||||||
EXPECT_CALL(*mock_encoder1, GetEncoderInfo())
|
EXPECT_CALL(*mock_encoder1, GetEncoderInfo())
|
||||||
.WillRepeatedly(Return(encoder_info));
|
.WillRepeatedly(Return(encoder_info));
|
||||||
|
|
||||||
EXPECT_CALL(*mock_encoder2, InitEncode(_, _, _))
|
EXPECT_CALL(*mock_encoder2, InitEncode(_, _))
|
||||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
||||||
EXPECT_CALL(*mock_encoder2, GetEncoderInfo())
|
EXPECT_CALL(*mock_encoder2, GetEncoderInfo())
|
||||||
.WillRepeatedly(Return(encoder_info));
|
.WillRepeatedly(Return(encoder_info));
|
||||||
|
|
||||||
EXPECT_CALL(*mock_encoder3, InitEncode(_, _, _))
|
EXPECT_CALL(*mock_encoder3, InitEncode(_, _))
|
||||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
||||||
EXPECT_CALL(*mock_encoder3, GetEncoderInfo())
|
EXPECT_CALL(*mock_encoder3, GetEncoderInfo())
|
||||||
.WillRepeatedly(Return(encoder_info));
|
.WillRepeatedly(Return(encoder_info));
|
||||||
|
|
||||||
EXPECT_CALL(*mock_encoder4, InitEncode(_, _, _))
|
EXPECT_CALL(*mock_encoder4, InitEncode(_, _))
|
||||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
||||||
EXPECT_CALL(*mock_encoder4, GetEncoderInfo())
|
EXPECT_CALL(*mock_encoder4, GetEncoderInfo())
|
||||||
.WillRepeatedly(Return(encoder_info));
|
.WillRepeatedly(Return(encoder_info));
|
||||||
@ -117,7 +122,7 @@ TEST(EncoderSimulcastProxy, ChoosesCorrectImplementation) {
|
|||||||
EncoderSimulcastProxy simulcast_disabled_proxy(&nonsimulcast_factory,
|
EncoderSimulcastProxy simulcast_disabled_proxy(&nonsimulcast_factory,
|
||||||
SdpVideoFormat("VP8"));
|
SdpVideoFormat("VP8"));
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
simulcast_disabled_proxy.InitEncode(&codec_settings, 4, 1200));
|
simulcast_disabled_proxy.InitEncode(&codec_settings, kSettings));
|
||||||
EXPECT_EQ(kSimulcastAdaptedImplementationName,
|
EXPECT_EQ(kSimulcastAdaptedImplementationName,
|
||||||
simulcast_disabled_proxy.GetEncoderInfo().implementation_name);
|
simulcast_disabled_proxy.GetEncoderInfo().implementation_name);
|
||||||
|
|
||||||
@ -130,7 +135,7 @@ TEST(EncoderSimulcastProxy, ForwardsTrustedSetting) {
|
|||||||
NiceMock<MockVideoEncoder>* mock_encoder = new NiceMock<MockVideoEncoder>();
|
NiceMock<MockVideoEncoder>* mock_encoder = new NiceMock<MockVideoEncoder>();
|
||||||
NiceMock<MockVideoEncoderFactory> simulcast_factory;
|
NiceMock<MockVideoEncoderFactory> simulcast_factory;
|
||||||
|
|
||||||
EXPECT_CALL(*mock_encoder, InitEncode(_, _, _))
|
EXPECT_CALL(*mock_encoder, InitEncode(_, _))
|
||||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
||||||
|
|
||||||
EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_))
|
EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_))
|
||||||
@ -142,7 +147,7 @@ TEST(EncoderSimulcastProxy, ForwardsTrustedSetting) {
|
|||||||
VideoCodec codec_settings;
|
VideoCodec codec_settings;
|
||||||
webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
|
webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
simulcast_enabled_proxy.InitEncode(&codec_settings, 4, 1200));
|
simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings));
|
||||||
|
|
||||||
VideoEncoder::EncoderInfo info;
|
VideoEncoder::EncoderInfo info;
|
||||||
info.has_trusted_rate_controller = true;
|
info.has_trusted_rate_controller = true;
|
||||||
@ -156,7 +161,7 @@ TEST(EncoderSimulcastProxy, ForwardsHardwareAccelerated) {
|
|||||||
NiceMock<MockVideoEncoder>* mock_encoder = new NiceMock<MockVideoEncoder>();
|
NiceMock<MockVideoEncoder>* mock_encoder = new NiceMock<MockVideoEncoder>();
|
||||||
NiceMock<MockVideoEncoderFactory> simulcast_factory;
|
NiceMock<MockVideoEncoderFactory> simulcast_factory;
|
||||||
|
|
||||||
EXPECT_CALL(*mock_encoder, InitEncode(_, _, _))
|
EXPECT_CALL(*mock_encoder, InitEncode(_, _))
|
||||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
||||||
|
|
||||||
EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_))
|
EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_))
|
||||||
@ -168,7 +173,7 @@ TEST(EncoderSimulcastProxy, ForwardsHardwareAccelerated) {
|
|||||||
VideoCodec codec_settings;
|
VideoCodec codec_settings;
|
||||||
webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
|
webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
simulcast_enabled_proxy.InitEncode(&codec_settings, 4, 1200));
|
simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings));
|
||||||
|
|
||||||
VideoEncoder::EncoderInfo info;
|
VideoEncoder::EncoderInfo info;
|
||||||
|
|
||||||
@ -186,7 +191,7 @@ TEST(EncoderSimulcastProxy, ForwardsInternalSource) {
|
|||||||
NiceMock<MockVideoEncoder>* mock_encoder = new NiceMock<MockVideoEncoder>();
|
NiceMock<MockVideoEncoder>* mock_encoder = new NiceMock<MockVideoEncoder>();
|
||||||
NiceMock<MockVideoEncoderFactory> simulcast_factory;
|
NiceMock<MockVideoEncoderFactory> simulcast_factory;
|
||||||
|
|
||||||
EXPECT_CALL(*mock_encoder, InitEncode(_, _, _))
|
EXPECT_CALL(*mock_encoder, InitEncode(_, _))
|
||||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
||||||
|
|
||||||
EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_))
|
EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_))
|
||||||
@ -198,7 +203,7 @@ TEST(EncoderSimulcastProxy, ForwardsInternalSource) {
|
|||||||
VideoCodec codec_settings;
|
VideoCodec codec_settings;
|
||||||
webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
|
webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
simulcast_enabled_proxy.InitEncode(&codec_settings, 4, 1200));
|
simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings));
|
||||||
|
|
||||||
VideoEncoder::EncoderInfo info;
|
VideoEncoder::EncoderInfo info;
|
||||||
|
|
||||||
|
|||||||
@ -141,6 +141,13 @@ int32_t FakeWebRtcVideoEncoder::InitEncode(
|
|||||||
const webrtc::VideoCodec* codecSettings,
|
const webrtc::VideoCodec* codecSettings,
|
||||||
int32_t numberOfCores,
|
int32_t numberOfCores,
|
||||||
size_t maxPayloadSize) {
|
size_t maxPayloadSize) {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t FakeWebRtcVideoEncoder::InitEncode(
|
||||||
|
const webrtc::VideoCodec* codecSettings,
|
||||||
|
const VideoEncoder::Settings& settings) {
|
||||||
rtc::CritScope lock(&crit_);
|
rtc::CritScope lock(&crit_);
|
||||||
codec_settings_ = *codecSettings;
|
codec_settings_ = *codecSettings;
|
||||||
init_encode_event_.Set();
|
init_encode_event_.Set();
|
||||||
|
|||||||
@ -86,6 +86,8 @@ class FakeWebRtcVideoEncoder : public webrtc::VideoEncoder {
|
|||||||
int32_t InitEncode(const webrtc::VideoCodec* codecSettings,
|
int32_t InitEncode(const webrtc::VideoCodec* codecSettings,
|
||||||
int32_t numberOfCores,
|
int32_t numberOfCores,
|
||||||
size_t maxPayloadSize) override;
|
size_t maxPayloadSize) override;
|
||||||
|
int32_t InitEncode(const webrtc::VideoCodec* codecSettings,
|
||||||
|
const VideoEncoder::Settings& settings) override;
|
||||||
int32_t Encode(
|
int32_t Encode(
|
||||||
const webrtc::VideoFrame& inputImage,
|
const webrtc::VideoFrame& inputImage,
|
||||||
const std::vector<webrtc::VideoFrameType>* frame_types) override;
|
const std::vector<webrtc::VideoFrameType>* frame_types) override;
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include "api/video/video_codec_constants.h"
|
#include "api/video/video_codec_constants.h"
|
||||||
#include "api/video/video_frame_buffer.h"
|
#include "api/video/video_frame_buffer.h"
|
||||||
#include "api/video/video_rotation.h"
|
#include "api/video/video_rotation.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "api/video_codecs/video_encoder_factory.h"
|
#include "api/video_codecs/video_encoder_factory.h"
|
||||||
#include "modules/video_coding/include/video_error_codes.h"
|
#include "modules/video_coding/include/video_error_codes.h"
|
||||||
#include "modules/video_coding/utility/simulcast_rate_allocator.h"
|
#include "modules/video_coding/utility/simulcast_rate_allocator.h"
|
||||||
@ -170,9 +171,17 @@ int SimulcastEncoderAdapter::Release() {
|
|||||||
int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst,
|
int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst,
|
||||||
int number_of_cores,
|
int number_of_cores,
|
||||||
size_t max_payload_size) {
|
size_t max_payload_size) {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(eladalon): s/inst/codec_settings/g.
|
||||||
|
int SimulcastEncoderAdapter::InitEncode(
|
||||||
|
const VideoCodec* inst,
|
||||||
|
const VideoEncoder::Settings& settings) {
|
||||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||||
|
|
||||||
if (number_of_cores < 1) {
|
if (settings.number_of_cores < 1) {
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +265,7 @@ int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst,
|
|||||||
codec_.codecType == webrtc::kVideoCodecVP8 ? "VP8" : "H264"));
|
codec_.codecType == webrtc::kVideoCodecVP8 ? "VP8" : "H264"));
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = encoder->InitEncode(&stream_codec, number_of_cores, max_payload_size);
|
ret = encoder->InitEncode(&stream_codec, settings);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
// Explicitly destroy the current encoder; because we haven't registered a
|
// Explicitly destroy the current encoder; because we haven't registered a
|
||||||
// StreamInfo for it yet, Release won't do anything about it.
|
// StreamInfo for it yet, Release won't do anything about it.
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/video_codecs/sdp_video_format.h"
|
#include "api/video_codecs/sdp_video_format.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "modules/video_coding/include/video_codec_interface.h"
|
#include "modules/video_coding/include/video_codec_interface.h"
|
||||||
#include "rtc_base/atomic_ops.h"
|
#include "rtc_base/atomic_ops.h"
|
||||||
#include "rtc_base/synchronization/sequence_checker.h"
|
#include "rtc_base/synchronization/sequence_checker.h"
|
||||||
@ -42,9 +43,11 @@ class RTC_EXPORT SimulcastEncoderAdapter : public VideoEncoder {
|
|||||||
|
|
||||||
// Implements VideoEncoder.
|
// Implements VideoEncoder.
|
||||||
int Release() override;
|
int Release() override;
|
||||||
int InitEncode(const VideoCodec* inst,
|
int InitEncode(const VideoCodec* codec_settings,
|
||||||
int number_of_cores,
|
int number_of_cores,
|
||||||
size_t max_payload_size) override;
|
size_t max_payload_size) override;
|
||||||
|
int InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const VideoEncoder::Settings& settings) override;
|
||||||
int Encode(const VideoFrame& input_image,
|
int Encode(const VideoFrame& input_image,
|
||||||
const std::vector<VideoFrameType>* frame_types) override;
|
const std::vector<VideoFrameType>* frame_types) override;
|
||||||
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
|
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
#include "api/test/video/function_video_decoder_factory.h"
|
#include "api/test/video/function_video_decoder_factory.h"
|
||||||
#include "api/test/video/function_video_encoder_factory.h"
|
#include "api/test/video/function_video_encoder_factory.h"
|
||||||
#include "api/video_codecs/sdp_video_format.h"
|
#include "api/video_codecs/sdp_video_format.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "api/video_codecs/video_encoder_factory.h"
|
#include "api/video_codecs/video_encoder_factory.h"
|
||||||
#include "common_video/include/video_frame_buffer.h"
|
#include "common_video/include/video_frame_buffer.h"
|
||||||
#include "media/base/media_constants.h"
|
#include "media/base/media_constants.h"
|
||||||
@ -43,6 +44,9 @@ namespace {
|
|||||||
constexpr int kDefaultWidth = 1280;
|
constexpr int kDefaultWidth = 1280;
|
||||||
constexpr int kDefaultHeight = 720;
|
constexpr int kDefaultHeight = 720;
|
||||||
|
|
||||||
|
const VideoEncoder::Capabilities kCapabilities(false);
|
||||||
|
const VideoEncoder::Settings kSettings(kCapabilities, 1, 1200);
|
||||||
|
|
||||||
std::unique_ptr<SimulcastTestFixture> CreateSpecificSimulcastTestFixture(
|
std::unique_ptr<SimulcastTestFixture> CreateSpecificSimulcastTestFixture(
|
||||||
VideoEncoderFactory* internal_encoder_factory) {
|
VideoEncoderFactory* internal_encoder_factory) {
|
||||||
std::unique_ptr<VideoEncoderFactory> encoder_factory =
|
std::unique_ptr<VideoEncoderFactory> encoder_factory =
|
||||||
@ -190,6 +194,11 @@ class MockVideoEncoder : public VideoEncoder {
|
|||||||
int32_t InitEncode(const VideoCodec* codecSettings,
|
int32_t InitEncode(const VideoCodec* codecSettings,
|
||||||
int32_t numberOfCores,
|
int32_t numberOfCores,
|
||||||
size_t maxPayloadSize) /* override */ {
|
size_t maxPayloadSize) /* override */ {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
int32_t InitEncode(const VideoCodec* codecSettings,
|
||||||
|
const VideoEncoder::Settings& settings) /* override */ {
|
||||||
codec_ = *codecSettings;
|
codec_ = *codecSettings;
|
||||||
return init_encode_return_value_;
|
return init_encode_return_value_;
|
||||||
}
|
}
|
||||||
@ -394,7 +403,7 @@ class TestSimulcastEncoderAdapterFake : public ::testing::Test,
|
|||||||
&codec_, static_cast<const int*>(kTestTemporalLayerProfile),
|
&codec_, static_cast<const int*>(kTestTemporalLayerProfile),
|
||||||
kVideoCodecVP8);
|
kVideoCodecVP8);
|
||||||
rate_allocator_.reset(new SimulcastRateAllocator(codec_));
|
rate_allocator_.reset(new SimulcastRateAllocator(codec_));
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
adapter_->RegisterEncodeCompleteCallback(this);
|
adapter_->RegisterEncodeCompleteCallback(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -491,7 +500,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, Reinit) {
|
|||||||
SetupCodec();
|
SetupCodec();
|
||||||
EXPECT_EQ(0, adapter_->Release());
|
EXPECT_EQ(0, adapter_->Release());
|
||||||
|
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
|
TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
|
||||||
@ -557,7 +566,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
|
|||||||
std::vector<VideoFrameType> frame_types;
|
std::vector<VideoFrameType> frame_types;
|
||||||
|
|
||||||
// Encode with three streams.
|
// Encode with three streams.
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
VerifyCodecSettings();
|
VerifyCodecSettings();
|
||||||
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
|
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
|
||||||
@ -585,7 +594,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
|
|||||||
codec_.width /= 2;
|
codec_.width /= 2;
|
||||||
codec_.height /= 2;
|
codec_.height /= 2;
|
||||||
codec_.numberOfSimulcastStreams = 2;
|
codec_.numberOfSimulcastStreams = 2;
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
|
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
|
||||||
std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
|
std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
|
||||||
@ -608,7 +617,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
|
|||||||
codec_.width /= 2;
|
codec_.width /= 2;
|
||||||
codec_.height /= 2;
|
codec_.height /= 2;
|
||||||
codec_.numberOfSimulcastStreams = 1;
|
codec_.numberOfSimulcastStreams = 1;
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
|
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
|
||||||
new_encoders = helper_->factory()->encoders();
|
new_encoders = helper_->factory()->encoders();
|
||||||
@ -626,7 +635,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
|
|||||||
codec_.width *= 4;
|
codec_.width *= 4;
|
||||||
codec_.height *= 4;
|
codec_.height *= 4;
|
||||||
codec_.numberOfSimulcastStreams = 3;
|
codec_.numberOfSimulcastStreams = 3;
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
|
rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
|
||||||
new_encoders = helper_->factory()->encoders();
|
new_encoders = helper_->factory()->encoders();
|
||||||
@ -680,7 +689,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
|
|||||||
|
|
||||||
// Reinitialize and verify that the new codec settings are the same.
|
// Reinitialize and verify that the new codec settings are the same.
|
||||||
EXPECT_EQ(0, adapter_->Release());
|
EXPECT_EQ(0, adapter_->Release());
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
const VideoCodec& codec_before = codecs_before[i];
|
const VideoCodec& codec_before = codecs_before[i];
|
||||||
const VideoCodec& codec_after = encoders[i]->codec();
|
const VideoCodec& codec_after = encoders[i]->codec();
|
||||||
@ -735,7 +744,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
|
|||||||
|
|
||||||
// Reinitialize.
|
// Reinitialize.
|
||||||
EXPECT_EQ(0, adapter_->Release());
|
EXPECT_EQ(0, adapter_->Release());
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
adapter_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
rate_allocator_->GetAllocation(1200, 30), 30.0));
|
rate_allocator_->GetAllocation(1200, 30), 30.0));
|
||||||
|
|
||||||
@ -758,14 +767,14 @@ TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
|
|||||||
&codec_, static_cast<const int*>(kTestTemporalLayerProfile),
|
&codec_, static_cast<const int*>(kTestTemporalLayerProfile),
|
||||||
kVideoCodecVP8);
|
kVideoCodecVP8);
|
||||||
codec_.numberOfSimulcastStreams = 1;
|
codec_.numberOfSimulcastStreams = 1;
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
adapter_->RegisterEncodeCompleteCallback(this);
|
adapter_->RegisterEncodeCompleteCallback(this);
|
||||||
ASSERT_EQ(1u, helper_->factory()->encoders().size());
|
ASSERT_EQ(1u, helper_->factory()->encoders().size());
|
||||||
helper_->factory()->encoders()[0]->set_supports_native_handle(true);
|
helper_->factory()->encoders()[0]->set_supports_native_handle(true);
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
|
EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
|
||||||
helper_->factory()->encoders()[0]->set_supports_native_handle(false);
|
helper_->factory()->encoders()[0]->set_supports_native_handle(false);
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
|
EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -775,7 +784,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
|
|||||||
kVideoCodecVP8);
|
kVideoCodecVP8);
|
||||||
codec_.minBitrate = 50;
|
codec_.minBitrate = 50;
|
||||||
codec_.numberOfSimulcastStreams = 1;
|
codec_.numberOfSimulcastStreams = 1;
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
rate_allocator_.reset(new SimulcastRateAllocator(codec_));
|
rate_allocator_.reset(new SimulcastRateAllocator(codec_));
|
||||||
|
|
||||||
// Above min should be respected.
|
// Above min should be respected.
|
||||||
@ -811,14 +820,14 @@ TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
|
|||||||
encoder_names.push_back("codec2");
|
encoder_names.push_back("codec2");
|
||||||
encoder_names.push_back("codec3");
|
encoder_names.push_back("codec3");
|
||||||
helper_->factory()->SetEncoderNames(encoder_names);
|
helper_->factory()->SetEncoderNames(encoder_names);
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_EQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
|
EXPECT_EQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
|
||||||
adapter_->GetEncoderInfo().implementation_name);
|
adapter_->GetEncoderInfo().implementation_name);
|
||||||
|
|
||||||
// Single streams should not expose "SimulcastEncoderAdapter" in name.
|
// Single streams should not expose "SimulcastEncoderAdapter" in name.
|
||||||
EXPECT_EQ(0, adapter_->Release());
|
EXPECT_EQ(0, adapter_->Release());
|
||||||
codec_.numberOfSimulcastStreams = 1;
|
codec_.numberOfSimulcastStreams = 1;
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
adapter_->RegisterEncodeCompleteCallback(this);
|
adapter_->RegisterEncodeCompleteCallback(this);
|
||||||
ASSERT_EQ(1u, helper_->factory()->encoders().size());
|
ASSERT_EQ(1u, helper_->factory()->encoders().size());
|
||||||
EXPECT_EQ("codec1", adapter_->GetEncoderInfo().implementation_name);
|
EXPECT_EQ("codec1", adapter_->GetEncoderInfo().implementation_name);
|
||||||
@ -830,7 +839,7 @@ TEST_F(TestSimulcastEncoderAdapterFake,
|
|||||||
&codec_, static_cast<const int*>(kTestTemporalLayerProfile),
|
&codec_, static_cast<const int*>(kTestTemporalLayerProfile),
|
||||||
kVideoCodecVP8);
|
kVideoCodecVP8);
|
||||||
codec_.numberOfSimulcastStreams = 3;
|
codec_.numberOfSimulcastStreams = 3;
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
adapter_->RegisterEncodeCompleteCallback(this);
|
adapter_->RegisterEncodeCompleteCallback(this);
|
||||||
ASSERT_EQ(3u, helper_->factory()->encoders().size());
|
ASSERT_EQ(3u, helper_->factory()->encoders().size());
|
||||||
for (MockVideoEncoder* encoder : helper_->factory()->encoders())
|
for (MockVideoEncoder* encoder : helper_->factory()->encoders())
|
||||||
@ -840,7 +849,7 @@ TEST_F(TestSimulcastEncoderAdapterFake,
|
|||||||
EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
|
EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
|
||||||
// Once all do, then the adapter claims support.
|
// Once all do, then the adapter claims support.
|
||||||
helper_->factory()->encoders()[0]->set_supports_native_handle(true);
|
helper_->factory()->encoders()[0]->set_supports_native_handle(true);
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
|
EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -872,12 +881,12 @@ TEST_F(TestSimulcastEncoderAdapterFake,
|
|||||||
codec_.numberOfSimulcastStreams = 3;
|
codec_.numberOfSimulcastStreams = 3;
|
||||||
// High start bitrate, so all streams are enabled.
|
// High start bitrate, so all streams are enabled.
|
||||||
codec_.startBitrate = 3000;
|
codec_.startBitrate = 3000;
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
adapter_->RegisterEncodeCompleteCallback(this);
|
adapter_->RegisterEncodeCompleteCallback(this);
|
||||||
ASSERT_EQ(3u, helper_->factory()->encoders().size());
|
ASSERT_EQ(3u, helper_->factory()->encoders().size());
|
||||||
for (MockVideoEncoder* encoder : helper_->factory()->encoders())
|
for (MockVideoEncoder* encoder : helper_->factory()->encoders())
|
||||||
encoder->set_supports_native_handle(true);
|
encoder->set_supports_native_handle(true);
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
|
EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
|
||||||
|
|
||||||
rtc::scoped_refptr<VideoFrameBuffer> buffer(
|
rtc::scoped_refptr<VideoFrameBuffer> buffer(
|
||||||
@ -901,7 +910,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) {
|
|||||||
&codec_, static_cast<const int*>(kTestTemporalLayerProfile),
|
&codec_, static_cast<const int*>(kTestTemporalLayerProfile),
|
||||||
kVideoCodecVP8);
|
kVideoCodecVP8);
|
||||||
codec_.numberOfSimulcastStreams = 3;
|
codec_.numberOfSimulcastStreams = 3;
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
adapter_->RegisterEncodeCompleteCallback(this);
|
adapter_->RegisterEncodeCompleteCallback(this);
|
||||||
ASSERT_EQ(3u, helper_->factory()->encoders().size());
|
ASSERT_EQ(3u, helper_->factory()->encoders().size());
|
||||||
// Tell the 2nd encoder to request software fallback.
|
// Tell the 2nd encoder to request software fallback.
|
||||||
@ -931,7 +940,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) {
|
|||||||
helper_->factory()->set_init_encode_return_value(
|
helper_->factory()->set_init_encode_return_value(
|
||||||
WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
|
WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
|
||||||
adapter_->InitEncode(&codec_, 1, 1200));
|
adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_TRUE(helper_->factory()->encoders().empty());
|
EXPECT_TRUE(helper_->factory()->encoders().empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -946,7 +955,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, DoesNotAlterMaxQpForScreenshare) {
|
|||||||
codec_.simulcastStream[0].qpMax = kHighMaxQp;
|
codec_.simulcastStream[0].qpMax = kHighMaxQp;
|
||||||
codec_.mode = VideoCodecMode::kScreensharing;
|
codec_.mode = VideoCodecMode::kScreensharing;
|
||||||
|
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_EQ(3u, helper_->factory()->encoders().size());
|
EXPECT_EQ(3u, helper_->factory()->encoders().size());
|
||||||
|
|
||||||
// Just check the lowest stream, which is the one that where the adapter
|
// Just check the lowest stream, which is the one that where the adapter
|
||||||
@ -961,7 +970,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, DoesNotAlterMaxQpForScreenshare) {
|
|||||||
|
|
||||||
// Change the max qp and try again.
|
// Change the max qp and try again.
|
||||||
codec_.simulcastStream[0].qpMax = kLowMaxQp;
|
codec_.simulcastStream[0].qpMax = kLowMaxQp;
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_EQ(3u, helper_->factory()->encoders().size());
|
EXPECT_EQ(3u, helper_->factory()->encoders().size());
|
||||||
ref_codec.qpMax = kLowMaxQp;
|
ref_codec.qpMax = kLowMaxQp;
|
||||||
VerifyCodec(ref_codec, 0);
|
VerifyCodec(ref_codec, 0);
|
||||||
@ -979,7 +988,7 @@ TEST_F(TestSimulcastEncoderAdapterFake,
|
|||||||
codec_.simulcastStream[2].qpMax = kHighMaxQp;
|
codec_.simulcastStream[2].qpMax = kHighMaxQp;
|
||||||
codec_.mode = VideoCodecMode::kScreensharing;
|
codec_.mode = VideoCodecMode::kScreensharing;
|
||||||
|
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_EQ(3u, helper_->factory()->encoders().size());
|
EXPECT_EQ(3u, helper_->factory()->encoders().size());
|
||||||
|
|
||||||
// Just check the lowest stream, which is the one that where the adapter
|
// Just check the lowest stream, which is the one that where the adapter
|
||||||
@ -994,7 +1003,7 @@ TEST_F(TestSimulcastEncoderAdapterFake,
|
|||||||
|
|
||||||
// Change the max qp and try again.
|
// Change the max qp and try again.
|
||||||
codec_.simulcastStream[2].qpMax = kLowMaxQp;
|
codec_.simulcastStream[2].qpMax = kLowMaxQp;
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_EQ(3u, helper_->factory()->encoders().size());
|
EXPECT_EQ(3u, helper_->factory()->encoders().size());
|
||||||
ref_codec.qpMax = kLowMaxQp;
|
ref_codec.qpMax = kLowMaxQp;
|
||||||
VerifyCodec(ref_codec, 2);
|
VerifyCodec(ref_codec, 2);
|
||||||
@ -1023,7 +1032,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ActivatesCorrectStreamsInInitEncode) {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Encode with three streams.
|
// Encode with three streams.
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
std::vector<MockVideoEncoder*> original_encoders =
|
std::vector<MockVideoEncoder*> original_encoders =
|
||||||
helper_->factory()->encoders();
|
helper_->factory()->encoders();
|
||||||
ASSERT_EQ(3u, original_encoders.size());
|
ASSERT_EQ(3u, original_encoders.size());
|
||||||
@ -1061,7 +1070,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, TrustedRateControl) {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
// No encoder trusted, so simulcast adapter should not be either.
|
// No encoder trusted, so simulcast adapter should not be either.
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
|
EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
|
||||||
|
|
||||||
// Encode with three streams.
|
// Encode with three streams.
|
||||||
@ -1072,18 +1081,18 @@ TEST_F(TestSimulcastEncoderAdapterFake, TrustedRateControl) {
|
|||||||
original_encoders[0]->set_has_trusted_rate_controller(true);
|
original_encoders[0]->set_has_trusted_rate_controller(true);
|
||||||
original_encoders[1]->set_has_trusted_rate_controller(true);
|
original_encoders[1]->set_has_trusted_rate_controller(true);
|
||||||
original_encoders[2]->set_has_trusted_rate_controller(true);
|
original_encoders[2]->set_has_trusted_rate_controller(true);
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_TRUE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
|
EXPECT_TRUE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
|
||||||
|
|
||||||
// One encoder not trusted, so simulcast adapter should not be either.
|
// One encoder not trusted, so simulcast adapter should not be either.
|
||||||
original_encoders[2]->set_has_trusted_rate_controller(false);
|
original_encoders[2]->set_has_trusted_rate_controller(false);
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
|
EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
|
||||||
|
|
||||||
// No encoder trusted, so simulcast adapter should not be either.
|
// No encoder trusted, so simulcast adapter should not be either.
|
||||||
original_encoders[0]->set_has_trusted_rate_controller(false);
|
original_encoders[0]->set_has_trusted_rate_controller(false);
|
||||||
original_encoders[1]->set_has_trusted_rate_controller(false);
|
original_encoders[1]->set_has_trusted_rate_controller(false);
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
|
EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1093,19 +1102,19 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReportsHardwareAccelerated) {
|
|||||||
kVideoCodecVP8);
|
kVideoCodecVP8);
|
||||||
codec_.numberOfSimulcastStreams = 3;
|
codec_.numberOfSimulcastStreams = 3;
|
||||||
adapter_->RegisterEncodeCompleteCallback(this);
|
adapter_->RegisterEncodeCompleteCallback(this);
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
ASSERT_EQ(3u, helper_->factory()->encoders().size());
|
ASSERT_EQ(3u, helper_->factory()->encoders().size());
|
||||||
|
|
||||||
// None of the encoders uses HW support, so simulcast adapter reports false.
|
// None of the encoders uses HW support, so simulcast adapter reports false.
|
||||||
for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
|
for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
|
||||||
encoder->set_is_hardware_accelerated(false);
|
encoder->set_is_hardware_accelerated(false);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_FALSE(adapter_->GetEncoderInfo().is_hardware_accelerated);
|
EXPECT_FALSE(adapter_->GetEncoderInfo().is_hardware_accelerated);
|
||||||
|
|
||||||
// One encoder uses HW support, so simulcast adapter reports true.
|
// One encoder uses HW support, so simulcast adapter reports true.
|
||||||
helper_->factory()->encoders()[2]->set_is_hardware_accelerated(true);
|
helper_->factory()->encoders()[2]->set_is_hardware_accelerated(true);
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_TRUE(adapter_->GetEncoderInfo().is_hardware_accelerated);
|
EXPECT_TRUE(adapter_->GetEncoderInfo().is_hardware_accelerated);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1115,19 +1124,19 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReportsInternalSource) {
|
|||||||
kVideoCodecVP8);
|
kVideoCodecVP8);
|
||||||
codec_.numberOfSimulcastStreams = 3;
|
codec_.numberOfSimulcastStreams = 3;
|
||||||
adapter_->RegisterEncodeCompleteCallback(this);
|
adapter_->RegisterEncodeCompleteCallback(this);
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
ASSERT_EQ(3u, helper_->factory()->encoders().size());
|
ASSERT_EQ(3u, helper_->factory()->encoders().size());
|
||||||
|
|
||||||
// All encoders have internal source, simulcast adapter reports true.
|
// All encoders have internal source, simulcast adapter reports true.
|
||||||
for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
|
for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
|
||||||
encoder->set_has_internal_source(true);
|
encoder->set_has_internal_source(true);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_TRUE(adapter_->GetEncoderInfo().has_internal_source);
|
EXPECT_TRUE(adapter_->GetEncoderInfo().has_internal_source);
|
||||||
|
|
||||||
// One encoder does not have internal source, simulcast adapter reports false.
|
// One encoder does not have internal source, simulcast adapter reports false.
|
||||||
helper_->factory()->encoders()[2]->set_has_internal_source(false);
|
helper_->factory()->encoders()[2]->set_has_internal_source(false);
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_FALSE(adapter_->GetEncoderInfo().has_internal_source);
|
EXPECT_FALSE(adapter_->GetEncoderInfo().has_internal_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1137,7 +1146,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReportsFpsAllocation) {
|
|||||||
kVideoCodecVP8);
|
kVideoCodecVP8);
|
||||||
codec_.numberOfSimulcastStreams = 3;
|
codec_.numberOfSimulcastStreams = 3;
|
||||||
adapter_->RegisterEncodeCompleteCallback(this);
|
adapter_->RegisterEncodeCompleteCallback(this);
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
ASSERT_EQ(3u, helper_->factory()->encoders().size());
|
ASSERT_EQ(3u, helper_->factory()->encoders().size());
|
||||||
|
|
||||||
// Combination of three different supported mode:
|
// Combination of three different supported mode:
|
||||||
@ -1155,7 +1164,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, ReportsFpsAllocation) {
|
|||||||
MockVideoEncoder* encoder = helper_->factory()->encoders()[i];
|
MockVideoEncoder* encoder = helper_->factory()->encoders()[i];
|
||||||
encoder->set_fps_allocation(expected_fps_allocation[i]);
|
encoder->set_fps_allocation(expected_fps_allocation[i]);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
EXPECT_THAT(adapter_->GetEncoderInfo().fps_allocation,
|
EXPECT_THAT(adapter_->GetEncoderInfo().fps_allocation,
|
||||||
::testing::ElementsAreArray(expected_fps_allocation));
|
::testing::ElementsAreArray(expected_fps_allocation));
|
||||||
}
|
}
|
||||||
@ -1172,7 +1181,7 @@ TEST_F(TestSimulcastEncoderAdapterFake, SetRateDistributesBandwithAllocation) {
|
|||||||
const DataRate bandwidth_allocation = target_bitrate + DataRate::kbps(600);
|
const DataRate bandwidth_allocation = target_bitrate + DataRate::kbps(600);
|
||||||
|
|
||||||
rate_allocator_.reset(new SimulcastRateAllocator(codec_));
|
rate_allocator_.reset(new SimulcastRateAllocator(codec_));
|
||||||
EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
|
EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
|
||||||
adapter_->RegisterEncodeCompleteCallback(this);
|
adapter_->RegisterEncodeCompleteCallback(this);
|
||||||
|
|
||||||
// Set bitrates so that we send all layers.
|
// Set bitrates so that we send all layers.
|
||||||
|
|||||||
@ -1895,7 +1895,9 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters_.config.rtp.lntf.enabled = HasLntf(codec_settings.codec);
|
const bool has_lntf = HasLntf(codec_settings.codec);
|
||||||
|
parameters_.config.rtp.lntf.enabled = has_lntf;
|
||||||
|
parameters_.config.encoder_settings.capabilities.loss_notification = has_lntf;
|
||||||
|
|
||||||
parameters_.config.rtp.nack.rtp_history_ms =
|
parameters_.config.rtp.nack.rtp_history_ms =
|
||||||
HasNack(codec_settings.codec) ? kNackHistoryMs : 0;
|
HasNack(codec_settings.codec) ? kNackHistoryMs : 0;
|
||||||
|
|||||||
@ -193,6 +193,12 @@ H264EncoderImpl::~H264EncoderImpl() {
|
|||||||
int32_t H264EncoderImpl::InitEncode(const VideoCodec* inst,
|
int32_t H264EncoderImpl::InitEncode(const VideoCodec* inst,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) {
|
size_t max_payload_size) {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t H264EncoderImpl::InitEncode(const VideoCodec* inst,
|
||||||
|
const VideoEncoder::Settings& settings) {
|
||||||
ReportInit();
|
ReportInit();
|
||||||
if (!inst || inst->codecType != kVideoCodecH264) {
|
if (!inst || inst->codecType != kVideoCodecH264) {
|
||||||
ReportError();
|
ReportError();
|
||||||
@ -226,8 +232,8 @@ int32_t H264EncoderImpl::InitEncode(const VideoCodec* inst,
|
|||||||
pictures_.resize(number_of_streams);
|
pictures_.resize(number_of_streams);
|
||||||
configurations_.resize(number_of_streams);
|
configurations_.resize(number_of_streams);
|
||||||
|
|
||||||
number_of_cores_ = number_of_cores;
|
number_of_cores_ = settings.number_of_cores;
|
||||||
max_payload_size_ = max_payload_size;
|
max_payload_size_ = settings.max_payload_size;
|
||||||
codec_ = *inst;
|
codec_ = *inst;
|
||||||
|
|
||||||
// Code expects simulcastStream resolutions to be correct, make sure they are
|
// Code expects simulcastStream resolutions to be correct, make sure they are
|
||||||
|
|||||||
@ -25,6 +25,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/video/i420_buffer.h"
|
#include "api/video/i420_buffer.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "common_video/h264/h264_bitstream_parser.h"
|
#include "common_video/h264/h264_bitstream_parser.h"
|
||||||
#include "modules/video_coding/codecs/h264/include/h264.h"
|
#include "modules/video_coding/codecs/h264/include/h264.h"
|
||||||
#include "modules/video_coding/utility/quality_scaler.h"
|
#include "modules/video_coding/utility/quality_scaler.h"
|
||||||
@ -66,6 +67,8 @@ class H264EncoderImpl : public H264Encoder {
|
|||||||
int32_t InitEncode(const VideoCodec* codec_settings,
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override;
|
size_t max_payload_size) override;
|
||||||
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const VideoEncoder::Settings& settings) override;
|
||||||
int32_t Release() override;
|
int32_t Release() override;
|
||||||
|
|
||||||
int32_t RegisterEncodeCompleteCallback(
|
int32_t RegisterEncodeCompleteCallback(
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "modules/video_coding/codecs/h264/h264_encoder_impl.h"
|
#include "modules/video_coding/codecs/h264/h264_encoder_impl.h"
|
||||||
|
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -20,6 +21,11 @@ namespace {
|
|||||||
const int kMaxPayloadSize = 1024;
|
const int kMaxPayloadSize = 1024;
|
||||||
const int kNumCores = 1;
|
const int kNumCores = 1;
|
||||||
|
|
||||||
|
const VideoEncoder::Capabilities kCapabilities(false);
|
||||||
|
const VideoEncoder::Settings kSettings(kCapabilities,
|
||||||
|
kNumCores,
|
||||||
|
kMaxPayloadSize);
|
||||||
|
|
||||||
void SetDefaultSettings(VideoCodec* codec_settings) {
|
void SetDefaultSettings(VideoCodec* codec_settings) {
|
||||||
codec_settings->codecType = kVideoCodecH264;
|
codec_settings->codecType = kVideoCodecH264;
|
||||||
codec_settings->maxFramerate = 60;
|
codec_settings->maxFramerate = 60;
|
||||||
@ -37,7 +43,7 @@ TEST(H264EncoderImplTest, CanInitializeWithDefaultParameters) {
|
|||||||
VideoCodec codec_settings;
|
VideoCodec codec_settings;
|
||||||
SetDefaultSettings(&codec_settings);
|
SetDefaultSettings(&codec_settings);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder.InitEncode(&codec_settings, kNumCores, kMaxPayloadSize));
|
encoder.InitEncode(&codec_settings, kSettings));
|
||||||
EXPECT_EQ(H264PacketizationMode::NonInterleaved,
|
EXPECT_EQ(H264PacketizationMode::NonInterleaved,
|
||||||
encoder.PacketizationModeForTesting());
|
encoder.PacketizationModeForTesting());
|
||||||
}
|
}
|
||||||
@ -49,7 +55,7 @@ TEST(H264EncoderImplTest, CanInitializeWithNonInterleavedModeExplicitly) {
|
|||||||
VideoCodec codec_settings;
|
VideoCodec codec_settings;
|
||||||
SetDefaultSettings(&codec_settings);
|
SetDefaultSettings(&codec_settings);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder.InitEncode(&codec_settings, kNumCores, kMaxPayloadSize));
|
encoder.InitEncode(&codec_settings, kSettings));
|
||||||
EXPECT_EQ(H264PacketizationMode::NonInterleaved,
|
EXPECT_EQ(H264PacketizationMode::NonInterleaved,
|
||||||
encoder.PacketizationModeForTesting());
|
encoder.PacketizationModeForTesting());
|
||||||
}
|
}
|
||||||
@ -61,7 +67,7 @@ TEST(H264EncoderImplTest, CanInitializeWithSingleNalUnitModeExplicitly) {
|
|||||||
VideoCodec codec_settings;
|
VideoCodec codec_settings;
|
||||||
SetDefaultSettings(&codec_settings);
|
SetDefaultSettings(&codec_settings);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder.InitEncode(&codec_settings, kNumCores, kMaxPayloadSize));
|
encoder.InitEncode(&codec_settings, kSettings));
|
||||||
EXPECT_EQ(H264PacketizationMode::SingleNalUnit,
|
EXPECT_EQ(H264PacketizationMode::SingleNalUnit,
|
||||||
encoder.PacketizationModeForTesting());
|
encoder.PacketizationModeForTesting());
|
||||||
}
|
}
|
||||||
@ -73,7 +79,7 @@ TEST(H264EncoderImplTest, CanInitializeWithRemovedParameter) {
|
|||||||
VideoCodec codec_settings;
|
VideoCodec codec_settings;
|
||||||
SetDefaultSettings(&codec_settings);
|
SetDefaultSettings(&codec_settings);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder.InitEncode(&codec_settings, kNumCores, kMaxPayloadSize));
|
encoder.InitEncode(&codec_settings, kSettings));
|
||||||
EXPECT_EQ(H264PacketizationMode::SingleNalUnit,
|
EXPECT_EQ(H264PacketizationMode::SingleNalUnit,
|
||||||
encoder.PacketizationModeForTesting());
|
encoder.PacketizationModeForTesting());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,6 +42,8 @@ class MultiplexEncoderAdapter : public VideoEncoder {
|
|||||||
int InitEncode(const VideoCodec* inst,
|
int InitEncode(const VideoCodec* inst,
|
||||||
int number_of_cores,
|
int number_of_cores,
|
||||||
size_t max_payload_size) override;
|
size_t max_payload_size) override;
|
||||||
|
int InitEncode(const VideoCodec* inst,
|
||||||
|
const VideoEncoder::Settings& settings) override;
|
||||||
int Encode(const VideoFrame& input_image,
|
int Encode(const VideoFrame& input_image,
|
||||||
const std::vector<VideoFrameType>* frame_types) override;
|
const std::vector<VideoFrameType>* frame_types) override;
|
||||||
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
|
int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "api/video/encoded_image.h"
|
#include "api/video/encoded_image.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "common_video/include/video_frame_buffer.h"
|
#include "common_video/include/video_frame_buffer.h"
|
||||||
#include "common_video/libyuv/include/webrtc_libyuv.h"
|
#include "common_video/libyuv/include/webrtc_libyuv.h"
|
||||||
#include "modules/include/module_common_types.h"
|
#include "modules/include/module_common_types.h"
|
||||||
@ -63,6 +64,13 @@ MultiplexEncoderAdapter::~MultiplexEncoderAdapter() {
|
|||||||
int MultiplexEncoderAdapter::InitEncode(const VideoCodec* inst,
|
int MultiplexEncoderAdapter::InitEncode(const VideoCodec* inst,
|
||||||
int number_of_cores,
|
int number_of_cores,
|
||||||
size_t max_payload_size) {
|
size_t max_payload_size) {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MultiplexEncoderAdapter::InitEncode(
|
||||||
|
const VideoCodec* inst,
|
||||||
|
const VideoEncoder::Settings& settings) {
|
||||||
const size_t buffer_size =
|
const size_t buffer_size =
|
||||||
CalcBufferSize(VideoType::kI420, inst->width, inst->height);
|
CalcBufferSize(VideoType::kI420, inst->width, inst->height);
|
||||||
multiplex_dummy_planes_.resize(buffer_size);
|
multiplex_dummy_planes_.resize(buffer_size);
|
||||||
@ -71,23 +79,23 @@ int MultiplexEncoderAdapter::InitEncode(const VideoCodec* inst,
|
|||||||
0x80);
|
0x80);
|
||||||
|
|
||||||
RTC_DCHECK_EQ(kVideoCodecMultiplex, inst->codecType);
|
RTC_DCHECK_EQ(kVideoCodecMultiplex, inst->codecType);
|
||||||
VideoCodec settings = *inst;
|
VideoCodec video_codec = *inst;
|
||||||
settings.codecType = PayloadStringToCodecType(associated_format_.name);
|
video_codec.codecType = PayloadStringToCodecType(associated_format_.name);
|
||||||
|
|
||||||
// Take over the key frame interval at adapter level, because we have to
|
// Take over the key frame interval at adapter level, because we have to
|
||||||
// sync the key frames for both sub-encoders.
|
// sync the key frames for both sub-encoders.
|
||||||
switch (settings.codecType) {
|
switch (video_codec.codecType) {
|
||||||
case kVideoCodecVP8:
|
case kVideoCodecVP8:
|
||||||
key_frame_interval_ = settings.VP8()->keyFrameInterval;
|
key_frame_interval_ = video_codec.VP8()->keyFrameInterval;
|
||||||
settings.VP8()->keyFrameInterval = 0;
|
video_codec.VP8()->keyFrameInterval = 0;
|
||||||
break;
|
break;
|
||||||
case kVideoCodecVP9:
|
case kVideoCodecVP9:
|
||||||
key_frame_interval_ = settings.VP9()->keyFrameInterval;
|
key_frame_interval_ = video_codec.VP9()->keyFrameInterval;
|
||||||
settings.VP9()->keyFrameInterval = 0;
|
video_codec.VP9()->keyFrameInterval = 0;
|
||||||
break;
|
break;
|
||||||
case kVideoCodecH264:
|
case kVideoCodecH264:
|
||||||
key_frame_interval_ = settings.H264()->keyFrameInterval;
|
key_frame_interval_ = video_codec.H264()->keyFrameInterval;
|
||||||
settings.H264()->keyFrameInterval = 0;
|
video_codec.H264()->keyFrameInterval = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -101,8 +109,7 @@ int MultiplexEncoderAdapter::InitEncode(const VideoCodec* inst,
|
|||||||
for (size_t i = 0; i < kAlphaCodecStreams; ++i) {
|
for (size_t i = 0; i < kAlphaCodecStreams; ++i) {
|
||||||
std::unique_ptr<VideoEncoder> encoder =
|
std::unique_ptr<VideoEncoder> encoder =
|
||||||
factory_->CreateVideoEncoder(associated_format_);
|
factory_->CreateVideoEncoder(associated_format_);
|
||||||
const int rv =
|
const int rv = encoder->InitEncode(&video_codec, settings);
|
||||||
encoder->InitEncode(&settings, number_of_cores, max_payload_size);
|
|
||||||
if (rv) {
|
if (rv) {
|
||||||
RTC_LOG(LS_ERROR) << "Failed to create multiplex codec index " << i;
|
RTC_LOG(LS_ERROR) << "Failed to create multiplex codec index " << i;
|
||||||
return rv;
|
return rv;
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||||
#include "modules/video_coding/codecs/test/video_codec_unittest.h"
|
#include "modules/video_coding/codecs/test/video_codec_unittest.h"
|
||||||
#include "modules/video_coding/include/video_error_codes.h"
|
#include "modules/video_coding/include/video_error_codes.h"
|
||||||
@ -25,6 +26,9 @@ static const int kHeight = 144; // Height of the input image.
|
|||||||
static const int kMaxFramerate = 30; // Arbitrary value.
|
static const int kMaxFramerate = 30; // Arbitrary value.
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
namespace {
|
||||||
|
const VideoEncoder::Capabilities kCapabilities(false);
|
||||||
|
}
|
||||||
|
|
||||||
EncodedImageCallback::Result
|
EncodedImageCallback::Result
|
||||||
VideoCodecUnitTest::FakeEncodeCompleteCallback::OnEncodedImage(
|
VideoCodecUnitTest::FakeEncodeCompleteCallback::OnEncodedImage(
|
||||||
@ -78,8 +82,10 @@ void VideoCodecUnitTest::SetUp() {
|
|||||||
decoder_->RegisterDecodeCompleteCallback(&decode_complete_callback_);
|
decoder_->RegisterDecodeCompleteCallback(&decode_complete_callback_);
|
||||||
|
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(
|
||||||
0 /* max payload size (unused) */));
|
&codec_settings_,
|
||||||
|
VideoEncoder::Settings(kCapabilities, 1 /* number of cores */,
|
||||||
|
0 /* max payload size (unused) */)));
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
decoder_->InitDecode(&codec_settings_, 1 /* number of cores */));
|
decoder_->InitDecode(&codec_settings_, 1 /* number of cores */));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,6 +28,7 @@ namespace webrtc {
|
|||||||
namespace test {
|
namespace test {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
const VideoEncoder::Capabilities kCapabilities(false);
|
||||||
|
|
||||||
int32_t InitEncoder(VideoCodecType codec_type, VideoEncoder* encoder) {
|
int32_t InitEncoder(VideoCodecType codec_type, VideoEncoder* encoder) {
|
||||||
VideoCodec codec;
|
VideoCodec codec;
|
||||||
@ -36,8 +37,9 @@ int32_t InitEncoder(VideoCodecType codec_type, VideoEncoder* encoder) {
|
|||||||
codec.height = 480;
|
codec.height = 480;
|
||||||
codec.maxFramerate = 30;
|
codec.maxFramerate = 30;
|
||||||
RTC_CHECK(encoder);
|
RTC_CHECK(encoder);
|
||||||
return encoder->InitEncode(&codec, 1 /* number_of_cores */,
|
return encoder->InitEncode(
|
||||||
1200 /* max_payload_size */);
|
&codec, VideoEncoder::Settings(kCapabilities, 1 /* number_of_cores */,
|
||||||
|
1200 /* max_payload_size */));
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t InitDecoder(VideoCodecType codec_type, VideoDecoder* decoder) {
|
int32_t InitDecoder(VideoCodecType codec_type, VideoDecoder* decoder) {
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
#include "api/video/video_frame_buffer.h"
|
#include "api/video/video_frame_buffer.h"
|
||||||
#include "api/video/video_rotation.h"
|
#include "api/video/video_rotation.h"
|
||||||
#include "api/video_codecs/video_codec.h"
|
#include "api/video_codecs/video_codec.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "common_video/h264/h264_common.h"
|
#include "common_video/h264/h264_common.h"
|
||||||
#include "common_video/libyuv/include/webrtc_libyuv.h"
|
#include "common_video/libyuv/include/webrtc_libyuv.h"
|
||||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||||
@ -45,6 +46,8 @@ namespace {
|
|||||||
const int kMsToRtpTimestamp = kVideoPayloadTypeFrequency / 1000;
|
const int kMsToRtpTimestamp = kVideoPayloadTypeFrequency / 1000;
|
||||||
const int kMaxBufferedInputFrames = 20;
|
const int kMaxBufferedInputFrames = 20;
|
||||||
|
|
||||||
|
const VideoEncoder::Capabilities kCapabilities(false);
|
||||||
|
|
||||||
size_t GetMaxNaluSizeBytes(const EncodedImage& encoded_frame,
|
size_t GetMaxNaluSizeBytes(const EncodedImage& encoded_frame,
|
||||||
const VideoCodecTestFixture::Config& config) {
|
const VideoCodecTestFixture::Config& config) {
|
||||||
if (config.codec_settings.codecType != kVideoCodecH264)
|
if (config.codec_settings.codecType != kVideoCodecH264)
|
||||||
@ -207,9 +210,11 @@ VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder,
|
|||||||
WEBRTC_VIDEO_CODEC_OK);
|
WEBRTC_VIDEO_CODEC_OK);
|
||||||
|
|
||||||
// Initialize codecs so that they are ready to receive frames.
|
// Initialize codecs so that they are ready to receive frames.
|
||||||
RTC_CHECK_EQ(encoder_->InitEncode(&config_.codec_settings,
|
RTC_CHECK_EQ(encoder_->InitEncode(
|
||||||
static_cast<int>(config_.NumberOfCores()),
|
&config_.codec_settings,
|
||||||
config_.max_payload_size_bytes),
|
VideoEncoder::Settings(
|
||||||
|
kCapabilities, static_cast<int>(config_.NumberOfCores()),
|
||||||
|
config_.max_payload_size_bytes)),
|
||||||
WEBRTC_VIDEO_CODEC_OK);
|
WEBRTC_VIDEO_CODEC_OK);
|
||||||
|
|
||||||
for (size_t i = 0; i < num_simulcast_or_spatial_layers_; ++i) {
|
for (size_t i = 0; i < num_simulcast_or_spatial_layers_; ++i) {
|
||||||
|
|||||||
@ -66,7 +66,7 @@ class VideoProcessorTest : public ::testing::Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ExpectInit() {
|
void ExpectInit() {
|
||||||
EXPECT_CALL(encoder_mock_, InitEncode(_, _, _)).Times(1);
|
EXPECT_CALL(encoder_mock_, InitEncode(_, _)).Times(1);
|
||||||
EXPECT_CALL(encoder_mock_, RegisterEncodeCompleteCallback(_)).Times(1);
|
EXPECT_CALL(encoder_mock_, RegisterEncodeCompleteCallback(_)).Times(1);
|
||||||
EXPECT_CALL(*decoder_mock_, InitDecode(_, _)).Times(1);
|
EXPECT_CALL(*decoder_mock_, InitDecode(_, _)).Times(1);
|
||||||
EXPECT_CALL(*decoder_mock_, RegisterDecodeCompleteCallback(_)).Times(1);
|
EXPECT_CALL(*decoder_mock_, RegisterDecodeCompleteCallback(_)).Times(1);
|
||||||
|
|||||||
@ -450,9 +450,17 @@ void LibvpxVp8Encoder::SetStreamState(bool send_stream, int stream_idx) {
|
|||||||
send_stream_[stream_idx] = send_stream;
|
send_stream_[stream_idx] = send_stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
|
int LibvpxVp8Encoder::InitEncode(const VideoCodec* codec_settings,
|
||||||
int number_of_cores,
|
int number_of_cores,
|
||||||
size_t /*maxPayloadSize */) {
|
size_t max_payload_size) {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(eladalon): s/inst/codec_settings/g.
|
||||||
|
// TODO(bugs.webrtc.org/10720): Pass |capabilities| to frame buffer controller.
|
||||||
|
int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
|
||||||
|
const VideoEncoder::Settings& settings) {
|
||||||
if (inst == NULL) {
|
if (inst == NULL) {
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
||||||
}
|
}
|
||||||
@ -466,7 +474,7 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
|
|||||||
if (inst->width < 1 || inst->height < 1) {
|
if (inst->width < 1 || inst->height < 1) {
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
||||||
}
|
}
|
||||||
if (number_of_cores < 1) {
|
if (settings.number_of_cores < 1) {
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
||||||
}
|
}
|
||||||
if (inst->VP8().automaticResizeOn && inst->numberOfSimulcastStreams > 1) {
|
if (inst->VP8().automaticResizeOn && inst->numberOfSimulcastStreams > 1) {
|
||||||
@ -492,7 +500,7 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
|
|||||||
}
|
}
|
||||||
RTC_DCHECK(frame_buffer_controller_);
|
RTC_DCHECK(frame_buffer_controller_);
|
||||||
|
|
||||||
number_of_cores_ = number_of_cores;
|
number_of_cores_ = settings.number_of_cores;
|
||||||
timestamp_ = 0;
|
timestamp_ = 0;
|
||||||
codec_ = *inst;
|
codec_ = *inst;
|
||||||
|
|
||||||
@ -611,7 +619,7 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
|
|||||||
// Determine number of threads based on the image size and #cores.
|
// Determine number of threads based on the image size and #cores.
|
||||||
// TODO(fbarchard): Consider number of Simulcast layers.
|
// TODO(fbarchard): Consider number of Simulcast layers.
|
||||||
vpx_configs_[0].g_threads = NumberOfThreads(
|
vpx_configs_[0].g_threads = NumberOfThreads(
|
||||||
vpx_configs_[0].g_w, vpx_configs_[0].g_h, number_of_cores);
|
vpx_configs_[0].g_w, vpx_configs_[0].g_h, settings.number_of_cores);
|
||||||
|
|
||||||
// Creating a wrapper to the image - setting image data to NULL.
|
// Creating a wrapper to the image - setting image data to NULL.
|
||||||
// Actual pointer will be set in encode. Setting align to 1, as it
|
// Actual pointer will be set in encode. Setting align to 1, as it
|
||||||
|
|||||||
@ -48,6 +48,8 @@ class LibvpxVp8Encoder : public VideoEncoder {
|
|||||||
int InitEncode(const VideoCodec* codec_settings,
|
int InitEncode(const VideoCodec* codec_settings,
|
||||||
int number_of_cores,
|
int number_of_cores,
|
||||||
size_t max_payload_size) override;
|
size_t max_payload_size) override;
|
||||||
|
int InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const VideoEncoder::Settings& settings) override;
|
||||||
|
|
||||||
int Encode(const VideoFrame& input_image,
|
int Encode(const VideoFrame& input_image,
|
||||||
const std::vector<VideoFrameType>* frame_types) override;
|
const std::vector<VideoFrameType>* frame_types) override;
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "api/test/mock_video_decoder.h"
|
#include "api/test/mock_video_decoder.h"
|
||||||
#include "api/test/mock_video_encoder.h"
|
#include "api/test/mock_video_encoder.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||||
#include "common_video/libyuv/include/webrtc_libyuv.h"
|
#include "common_video/libyuv/include/webrtc_libyuv.h"
|
||||||
#include "common_video/test/utilities.h"
|
#include "common_video/test/utilities.h"
|
||||||
@ -51,6 +52,11 @@ constexpr int kDefaultMinPixelsPerFrame = 320 * 180;
|
|||||||
constexpr int kWidth = 172;
|
constexpr int kWidth = 172;
|
||||||
constexpr int kHeight = 144;
|
constexpr int kHeight = 144;
|
||||||
constexpr float kFramerateFps = 30;
|
constexpr float kFramerateFps = 30;
|
||||||
|
|
||||||
|
const VideoEncoder::Capabilities kCapabilities(false);
|
||||||
|
const VideoEncoder::Settings kSettings(kCapabilities,
|
||||||
|
kNumCores,
|
||||||
|
kMaxPayloadSize);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class TestVp8Impl : public VideoCodecUnitTest {
|
class TestVp8Impl : public VideoCodecUnitTest {
|
||||||
@ -117,7 +123,8 @@ TEST_F(TestVp8Impl, SetRates) {
|
|||||||
auto* const vpx = new NiceMock<MockLibvpxVp8Interface>();
|
auto* const vpx = new NiceMock<MockLibvpxVp8Interface>();
|
||||||
LibvpxVp8Encoder encoder((std::unique_ptr<LibvpxInterface>(vpx)));
|
LibvpxVp8Encoder encoder((std::unique_ptr<LibvpxInterface>(vpx)));
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder.InitEncode(&codec_settings_, 1, 1000));
|
encoder.InitEncode(&codec_settings_,
|
||||||
|
VideoEncoder::Settings(kCapabilities, 1, 1000)));
|
||||||
|
|
||||||
const uint32_t kBitrateBps = 300000;
|
const uint32_t kBitrateBps = 300000;
|
||||||
VideoBitrateAllocation bitrate_allocation;
|
VideoBitrateAllocation bitrate_allocation;
|
||||||
@ -143,7 +150,8 @@ TEST_F(TestVp8Impl, DynamicSetRates) {
|
|||||||
auto* const vpx = new NiceMock<MockLibvpxVp8Interface>();
|
auto* const vpx = new NiceMock<MockLibvpxVp8Interface>();
|
||||||
LibvpxVp8Encoder encoder((std::unique_ptr<LibvpxInterface>(vpx)));
|
LibvpxVp8Encoder encoder((std::unique_ptr<LibvpxInterface>(vpx)));
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder.InitEncode(&codec_settings_, 1, 1000));
|
encoder.InitEncode(&codec_settings_,
|
||||||
|
VideoEncoder::Settings(kCapabilities, 1, 1000)));
|
||||||
|
|
||||||
const uint32_t kBitrateBps = 300000;
|
const uint32_t kBitrateBps = 300000;
|
||||||
VideoEncoder::RateControlParameters rate_settings;
|
VideoEncoder::RateControlParameters rate_settings;
|
||||||
@ -199,7 +207,7 @@ TEST_F(TestVp8Impl, DynamicSetRates) {
|
|||||||
TEST_F(TestVp8Impl, EncodeFrameAndRelease) {
|
TEST_F(TestVp8Impl, EncodeFrameAndRelease) {
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
|
|
||||||
EncodedImage encoded_frame;
|
EncodedImage encoded_frame;
|
||||||
CodecSpecificInfo codec_specific_info;
|
CodecSpecificInfo codec_specific_info;
|
||||||
@ -257,7 +265,7 @@ TEST_F(TestVp8Impl, ChecksSimulcastSettings) {
|
|||||||
codec_settings_.simulcastStream[1] = {kWidth / 2, kHeight / 2, 30, 3,
|
codec_settings_.simulcastStream[1] = {kWidth / 2, kHeight / 2, 30, 3,
|
||||||
4000, 3000, 2000, 80};
|
4000, 3000, 2000, 80};
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
codec_settings_.numberOfSimulcastStreams = 3;
|
codec_settings_.numberOfSimulcastStreams = 3;
|
||||||
// Resolutions are not in ascending order.
|
// Resolutions are not in ascending order.
|
||||||
codec_settings_.simulcastStream[0] = {
|
codec_settings_.simulcastStream[0] = {
|
||||||
@ -267,7 +275,7 @@ TEST_F(TestVp8Impl, ChecksSimulcastSettings) {
|
|||||||
codec_settings_.simulcastStream[2] = {kWidth, kHeight, 30, 1,
|
codec_settings_.simulcastStream[2] = {kWidth, kHeight, 30, 1,
|
||||||
4000, 3000, 2000, 80};
|
4000, 3000, 2000, 80};
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
// Resolutions are not in ascending order.
|
// Resolutions are not in ascending order.
|
||||||
codec_settings_.simulcastStream[0] = {kWidth, kHeight, kFramerateFps, 1,
|
codec_settings_.simulcastStream[0] = {kWidth, kHeight, kFramerateFps, 1,
|
||||||
4000, 3000, 2000, 80};
|
4000, 3000, 2000, 80};
|
||||||
@ -276,7 +284,7 @@ TEST_F(TestVp8Impl, ChecksSimulcastSettings) {
|
|||||||
codec_settings_.simulcastStream[2] = {
|
codec_settings_.simulcastStream[2] = {
|
||||||
kWidth - 1, kHeight - 1, kFramerateFps, 1, 4000, 3000, 2000, 80};
|
kWidth - 1, kHeight - 1, kFramerateFps, 1, 4000, 3000, 2000, 80};
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
// Temporal layers do not match.
|
// Temporal layers do not match.
|
||||||
codec_settings_.simulcastStream[0] = {
|
codec_settings_.simulcastStream[0] = {
|
||||||
kWidth / 4, kHeight / 4, kFramerateFps, 1, 4000, 3000, 2000, 80};
|
kWidth / 4, kHeight / 4, kFramerateFps, 1, 4000, 3000, 2000, 80};
|
||||||
@ -285,7 +293,7 @@ TEST_F(TestVp8Impl, ChecksSimulcastSettings) {
|
|||||||
codec_settings_.simulcastStream[2] = {kWidth, kHeight, kFramerateFps, 3,
|
codec_settings_.simulcastStream[2] = {kWidth, kHeight, kFramerateFps, 3,
|
||||||
4000, 3000, 2000, 80};
|
4000, 3000, 2000, 80};
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
// Resolutions do not match codec config.
|
// Resolutions do not match codec config.
|
||||||
codec_settings_.simulcastStream[0] = {
|
codec_settings_.simulcastStream[0] = {
|
||||||
kWidth / 4 + 1, kHeight / 4 + 1, kFramerateFps, 1, 4000, 3000, 2000, 80};
|
kWidth / 4 + 1, kHeight / 4 + 1, kFramerateFps, 1, 4000, 3000, 2000, 80};
|
||||||
@ -294,7 +302,7 @@ TEST_F(TestVp8Impl, ChecksSimulcastSettings) {
|
|||||||
codec_settings_.simulcastStream[2] = {
|
codec_settings_.simulcastStream[2] = {
|
||||||
kWidth + 4, kHeight + 4, kFramerateFps, 1, 4000, 3000, 2000, 80};
|
kWidth + 4, kHeight + 4, kFramerateFps, 1, 4000, 3000, 2000, 80};
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
// Everything fine: scaling by 2, top resolution matches video, temporal
|
// Everything fine: scaling by 2, top resolution matches video, temporal
|
||||||
// settings are the same for all layers.
|
// settings are the same for all layers.
|
||||||
codec_settings_.simulcastStream[0] = {
|
codec_settings_.simulcastStream[0] = {
|
||||||
@ -304,7 +312,7 @@ TEST_F(TestVp8Impl, ChecksSimulcastSettings) {
|
|||||||
codec_settings_.simulcastStream[2] = {kWidth, kHeight, kFramerateFps, 1,
|
codec_settings_.simulcastStream[2] = {kWidth, kHeight, kFramerateFps, 1,
|
||||||
4000, 3000, 2000, 80};
|
4000, 3000, 2000, 80};
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
// Everything fine: custom scaling, top resolution matches video, temporal
|
// Everything fine: custom scaling, top resolution matches video, temporal
|
||||||
// settings are the same for all layers.
|
// settings are the same for all layers.
|
||||||
codec_settings_.simulcastStream[0] = {
|
codec_settings_.simulcastStream[0] = {
|
||||||
@ -314,7 +322,7 @@ TEST_F(TestVp8Impl, ChecksSimulcastSettings) {
|
|||||||
codec_settings_.simulcastStream[2] = {kWidth, kHeight, kFramerateFps, 1,
|
codec_settings_.simulcastStream[2] = {kWidth, kHeight, kFramerateFps, 1,
|
||||||
4000, 3000, 2000, 80};
|
4000, 3000, 2000, 80};
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBRTC_ANDROID)
|
#if defined(WEBRTC_ANDROID)
|
||||||
@ -378,7 +386,7 @@ TEST_F(TestVp8Impl, MAYBE_DecodeWithACompleteKeyFrame) {
|
|||||||
TEST_F(TestVp8Impl, EncoderWith2TemporalLayers) {
|
TEST_F(TestVp8Impl, EncoderWith2TemporalLayers) {
|
||||||
codec_settings_.VP8()->numberOfTemporalLayers = 2;
|
codec_settings_.VP8()->numberOfTemporalLayers = 2;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
|
|
||||||
// Temporal layer 0.
|
// Temporal layer 0.
|
||||||
EncodedImage encoded_frame;
|
EncodedImage encoded_frame;
|
||||||
@ -399,7 +407,7 @@ TEST_F(TestVp8Impl, ScalingDisabledIfAutomaticResizeOff) {
|
|||||||
codec_settings_.VP8()->frameDroppingOn = true;
|
codec_settings_.VP8()->frameDroppingOn = true;
|
||||||
codec_settings_.VP8()->automaticResizeOn = false;
|
codec_settings_.VP8()->automaticResizeOn = false;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
|
|
||||||
VideoEncoder::ScalingSettings settings =
|
VideoEncoder::ScalingSettings settings =
|
||||||
encoder_->GetEncoderInfo().scaling_settings;
|
encoder_->GetEncoderInfo().scaling_settings;
|
||||||
@ -410,7 +418,7 @@ TEST_F(TestVp8Impl, ScalingEnabledIfAutomaticResizeOn) {
|
|||||||
codec_settings_.VP8()->frameDroppingOn = true;
|
codec_settings_.VP8()->frameDroppingOn = true;
|
||||||
codec_settings_.VP8()->automaticResizeOn = true;
|
codec_settings_.VP8()->automaticResizeOn = true;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
|
|
||||||
VideoEncoder::ScalingSettings settings =
|
VideoEncoder::ScalingSettings settings =
|
||||||
encoder_->GetEncoderInfo().scaling_settings;
|
encoder_->GetEncoderInfo().scaling_settings;
|
||||||
@ -442,7 +450,7 @@ TEST_F(TestVp8Impl, DontDropKeyframes) {
|
|||||||
/* num_squares = */ absl::optional<int>(300));
|
/* num_squares = */ absl::optional<int>(300));
|
||||||
|
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
|
|
||||||
VideoBitrateAllocation bitrate_allocation;
|
VideoBitrateAllocation bitrate_allocation;
|
||||||
// Bitrate only enough for TL0.
|
// Bitrate only enough for TL0.
|
||||||
@ -480,7 +488,8 @@ TEST_F(TestVp8Impl, KeepsTimestampOnReencode) {
|
|||||||
return img;
|
return img;
|
||||||
}));
|
}));
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder.InitEncode(&codec_settings_, 1, 1000));
|
encoder.InitEncode(&codec_settings_,
|
||||||
|
VideoEncoder::Settings(kCapabilities, 1, 1000)));
|
||||||
MockEncodedImageCallback callback;
|
MockEncodedImageCallback callback;
|
||||||
encoder.RegisterEncodeCompleteCallback(&callback);
|
encoder.RegisterEncodeCompleteCallback(&callback);
|
||||||
|
|
||||||
@ -512,7 +521,7 @@ TEST_F(TestVp8Impl, GetEncoderInfoFpsAllocationTwoTemporalLayers) {
|
|||||||
codec_settings_.simulcastStream[0].maxBitrate = 100;
|
codec_settings_.simulcastStream[0].maxBitrate = 100;
|
||||||
codec_settings_.simulcastStream[0].numberOfTemporalLayers = 2;
|
codec_settings_.simulcastStream[0].numberOfTemporalLayers = 2;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
|
|
||||||
FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
|
FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
|
||||||
expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 2);
|
expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 2);
|
||||||
@ -530,7 +539,7 @@ TEST_F(TestVp8Impl, GetEncoderInfoFpsAllocationThreeTemporalLayers) {
|
|||||||
codec_settings_.simulcastStream[0].maxBitrate = 100;
|
codec_settings_.simulcastStream[0].maxBitrate = 100;
|
||||||
codec_settings_.simulcastStream[0].numberOfTemporalLayers = 3;
|
codec_settings_.simulcastStream[0].numberOfTemporalLayers = 3;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
|
|
||||||
FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
|
FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
|
||||||
expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 4);
|
expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 4);
|
||||||
@ -553,7 +562,7 @@ TEST_F(TestVp8Impl, GetEncoderInfoFpsAllocationScreenshareLayers) {
|
|||||||
kLegacyScreenshareTl1BitrateKbps;
|
kLegacyScreenshareTl1BitrateKbps;
|
||||||
codec_settings_.simulcastStream[0].numberOfTemporalLayers = 2;
|
codec_settings_.simulcastStream[0].numberOfTemporalLayers = 2;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
|
|
||||||
// Expect empty vector, since this mode doesn't have a fixed framerate.
|
// Expect empty vector, since this mode doesn't have a fixed framerate.
|
||||||
FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
|
FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
|
||||||
@ -581,7 +590,7 @@ TEST_F(TestVp8Impl, GetEncoderInfoFpsAllocationSimulcastVideo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize));
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
|
|
||||||
FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
|
FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
|
||||||
expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 4);
|
expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 4);
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "api/video/color_space.h"
|
#include "api/video/color_space.h"
|
||||||
#include "api/video/i420_buffer.h"
|
#include "api/video/i420_buffer.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "common_video/libyuv/include/webrtc_libyuv.h"
|
#include "common_video/libyuv/include/webrtc_libyuv.h"
|
||||||
#include "media/base/vp9_profile.h"
|
#include "media/base/vp9_profile.h"
|
||||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||||
@ -31,6 +32,11 @@ using FramerateFractions =
|
|||||||
namespace {
|
namespace {
|
||||||
const size_t kWidth = 1280;
|
const size_t kWidth = 1280;
|
||||||
const size_t kHeight = 720;
|
const size_t kHeight = 720;
|
||||||
|
|
||||||
|
const VideoEncoder::Capabilities kCapabilities(false);
|
||||||
|
const VideoEncoder::Settings kSettings(kCapabilities,
|
||||||
|
/*number_of_cores=*/1,
|
||||||
|
/*max_payload_size=*/0);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class TestVp9Impl : public VideoCodecUnitTest {
|
class TestVp9Impl : public VideoCodecUnitTest {
|
||||||
@ -199,8 +205,7 @@ TEST_F(TestVp9Impl, EncoderWith2TemporalLayers) {
|
|||||||
// Tl0PidIdx is only used in non-flexible mode.
|
// Tl0PidIdx is only used in non-flexible mode.
|
||||||
codec_settings_.VP9()->flexibleMode = false;
|
codec_settings_.VP9()->flexibleMode = false;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
// Temporal layer 0.
|
// Temporal layer 0.
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
@ -229,8 +234,7 @@ TEST_F(TestVp9Impl, EncoderWith2TemporalLayers) {
|
|||||||
TEST_F(TestVp9Impl, EncoderWith2SpatialLayers) {
|
TEST_F(TestVp9Impl, EncoderWith2SpatialLayers) {
|
||||||
codec_settings_.VP9()->numberOfSpatialLayers = 2;
|
codec_settings_.VP9()->numberOfSpatialLayers = 2;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
SetWaitForEncodedFramesThreshold(2);
|
SetWaitForEncodedFramesThreshold(2);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
@ -273,8 +277,7 @@ TEST_F(TestVp9Impl, EncoderExplicitLayering) {
|
|||||||
codec_settings_.spatialLayers[1].maxFramerate = codec_settings_.maxFramerate;
|
codec_settings_.spatialLayers[1].maxFramerate = codec_settings_.maxFramerate;
|
||||||
|
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
// Ensure it fails if scaling factors in horz/vert dimentions are different.
|
// Ensure it fails if scaling factors in horz/vert dimentions are different.
|
||||||
codec_settings_.spatialLayers[0].width = codec_settings_.width;
|
codec_settings_.spatialLayers[0].width = codec_settings_.width;
|
||||||
@ -282,8 +285,7 @@ TEST_F(TestVp9Impl, EncoderExplicitLayering) {
|
|||||||
codec_settings_.spatialLayers[1].width = codec_settings_.width;
|
codec_settings_.spatialLayers[1].width = codec_settings_.width;
|
||||||
codec_settings_.spatialLayers[1].height = codec_settings_.height;
|
codec_settings_.spatialLayers[1].height = codec_settings_.height;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_PARAMETER,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_PARAMETER,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
// Ensure it fails if scaling factor is not power of two.
|
// Ensure it fails if scaling factor is not power of two.
|
||||||
codec_settings_.spatialLayers[0].width = codec_settings_.width / 3;
|
codec_settings_.spatialLayers[0].width = codec_settings_.width / 3;
|
||||||
@ -291,8 +293,7 @@ TEST_F(TestVp9Impl, EncoderExplicitLayering) {
|
|||||||
codec_settings_.spatialLayers[1].width = codec_settings_.width;
|
codec_settings_.spatialLayers[1].width = codec_settings_.width;
|
||||||
codec_settings_.spatialLayers[1].height = codec_settings_.height;
|
codec_settings_.spatialLayers[1].height = codec_settings_.height;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_PARAMETER,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_PARAMETER,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestVp9Impl, EnableDisableSpatialLayers) {
|
TEST_F(TestVp9Impl, EnableDisableSpatialLayers) {
|
||||||
@ -309,8 +310,7 @@ TEST_F(TestVp9Impl, EnableDisableSpatialLayers) {
|
|||||||
codec_settings_.VP9()->frameDroppingOn = true;
|
codec_settings_.VP9()->frameDroppingOn = true;
|
||||||
|
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
VideoBitrateAllocation bitrate_allocation;
|
VideoBitrateAllocation bitrate_allocation;
|
||||||
for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) {
|
for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) {
|
||||||
@ -357,8 +357,7 @@ TEST_F(TestVp9Impl, EndOfPicture) {
|
|||||||
ConfigureSvc(num_spatial_layers);
|
ConfigureSvc(num_spatial_layers);
|
||||||
|
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
// Encode both base and upper layers. Check that end-of-superframe flag is
|
// Encode both base and upper layers. Check that end-of-superframe flag is
|
||||||
// set on upper layer frame but not on base layer frame.
|
// set on upper layer frame but not on base layer frame.
|
||||||
@ -385,8 +384,7 @@ TEST_F(TestVp9Impl, EndOfPicture) {
|
|||||||
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
bitrate_allocation, codec_settings_.maxFramerate));
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
SetWaitForEncodedFramesThreshold(1);
|
SetWaitForEncodedFramesThreshold(1);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
@ -415,8 +413,7 @@ TEST_F(TestVp9Impl, InterLayerPred) {
|
|||||||
for (const InterLayerPredMode inter_layer_pred : inter_layer_pred_modes) {
|
for (const InterLayerPredMode inter_layer_pred : inter_layer_pred_modes) {
|
||||||
codec_settings_.VP9()->interLayerPred = inter_layer_pred;
|
codec_settings_.VP9()->interLayerPred = inter_layer_pred;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
bitrate_allocation, codec_settings_.maxFramerate));
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
@ -485,8 +482,7 @@ TEST_F(TestVp9Impl,
|
|||||||
for (const InterLayerPredMode inter_layer_pred : inter_layer_pred_modes) {
|
for (const InterLayerPredMode inter_layer_pred : inter_layer_pred_modes) {
|
||||||
codec_settings_.VP9()->interLayerPred = inter_layer_pred;
|
codec_settings_.VP9()->interLayerPred = inter_layer_pred;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
VideoBitrateAllocation bitrate_allocation;
|
VideoBitrateAllocation bitrate_allocation;
|
||||||
for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) {
|
for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) {
|
||||||
@ -544,8 +540,7 @@ TEST_F(TestVp9Impl,
|
|||||||
for (const InterLayerPredMode inter_layer_pred : inter_layer_pred_modes) {
|
for (const InterLayerPredMode inter_layer_pred : inter_layer_pred_modes) {
|
||||||
codec_settings_.VP9()->interLayerPred = inter_layer_pred;
|
codec_settings_.VP9()->interLayerPred = inter_layer_pred;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
VideoBitrateAllocation bitrate_allocation;
|
VideoBitrateAllocation bitrate_allocation;
|
||||||
for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) {
|
for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) {
|
||||||
@ -595,8 +590,7 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerInTheSameGof) {
|
|||||||
|
|
||||||
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn;
|
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
VideoBitrateAllocation bitrate_allocation;
|
VideoBitrateAllocation bitrate_allocation;
|
||||||
|
|
||||||
@ -670,8 +664,7 @@ TEST_F(TestVp9Impl, EnablingDisablingUpperLayerAccrossGof) {
|
|||||||
|
|
||||||
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn;
|
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
VideoBitrateAllocation bitrate_allocation;
|
VideoBitrateAllocation bitrate_allocation;
|
||||||
|
|
||||||
@ -761,8 +754,7 @@ TEST_F(TestVp9Impl, EnablingNewLayerIsDelayedInScreenshareAndAddsSsInfo) {
|
|||||||
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn;
|
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn;
|
||||||
codec_settings_.VP9()->flexibleMode = true;
|
codec_settings_.VP9()->flexibleMode = true;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
// Enable all but the last layer.
|
// Enable all but the last layer.
|
||||||
VideoBitrateAllocation bitrate_allocation;
|
VideoBitrateAllocation bitrate_allocation;
|
||||||
@ -830,8 +822,7 @@ TEST_F(TestVp9Impl, ScreenshareFrameDropping) {
|
|||||||
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn;
|
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn;
|
||||||
codec_settings_.VP9()->flexibleMode = true;
|
codec_settings_.VP9()->flexibleMode = true;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
// Enable all but the last layer.
|
// Enable all but the last layer.
|
||||||
VideoBitrateAllocation bitrate_allocation;
|
VideoBitrateAllocation bitrate_allocation;
|
||||||
@ -924,8 +915,7 @@ TEST_F(TestVp9Impl, RemovingLayerIsNotDelayedInScreenshareAndAddsSsInfo) {
|
|||||||
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn;
|
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn;
|
||||||
codec_settings_.VP9()->flexibleMode = true;
|
codec_settings_.VP9()->flexibleMode = true;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
// All layers are enabled from the start.
|
// All layers are enabled from the start.
|
||||||
VideoBitrateAllocation bitrate_allocation;
|
VideoBitrateAllocation bitrate_allocation;
|
||||||
@ -1007,8 +997,7 @@ TEST_F(TestVp9Impl, DisableNewLayerInVideoDelaysSsInfoTillTL0) {
|
|||||||
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOnKeyPic;
|
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOnKeyPic;
|
||||||
codec_settings_.VP9()->flexibleMode = false;
|
codec_settings_.VP9()->flexibleMode = false;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
// Enable all the layers.
|
// Enable all the layers.
|
||||||
VideoBitrateAllocation bitrate_allocation;
|
VideoBitrateAllocation bitrate_allocation;
|
||||||
@ -1069,8 +1058,7 @@ TEST_F(TestVp9Impl,
|
|||||||
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn;
|
codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn;
|
||||||
|
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
VideoBitrateAllocation bitrate_allocation;
|
VideoBitrateAllocation bitrate_allocation;
|
||||||
bitrate_allocation.SetBitrate(
|
bitrate_allocation.SetBitrate(
|
||||||
@ -1089,8 +1077,7 @@ TEST_F(TestVp9Impl,
|
|||||||
TEST_F(TestVp9Impl, ScalabilityStructureIsAvailableInFlexibleMode) {
|
TEST_F(TestVp9Impl, ScalabilityStructureIsAvailableInFlexibleMode) {
|
||||||
codec_settings_.VP9()->flexibleMode = true;
|
codec_settings_.VP9()->flexibleMode = true;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->Encode(*NextInputFrame(), nullptr));
|
encoder_->Encode(*NextInputFrame(), nullptr));
|
||||||
@ -1123,8 +1110,7 @@ TEST_F(TestVp9Impl, EncoderInfoFpsAllocation) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
|
FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
|
||||||
expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 4);
|
expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 4);
|
||||||
@ -1161,8 +1147,7 @@ TEST_F(TestVp9Impl, EncoderInfoFpsAllocationFlexibleMode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
// No temporal layers allowed when spatial layers have different fps targets.
|
// No temporal layers allowed when spatial layers have different fps targets.
|
||||||
FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
|
FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
|
||||||
@ -1195,8 +1180,7 @@ TEST_P(TestVp9ImplWithLayering, FlexibleMode) {
|
|||||||
codec_settings_.VP9()->numberOfSpatialLayers = num_spatial_layers_;
|
codec_settings_.VP9()->numberOfSpatialLayers = num_spatial_layers_;
|
||||||
codec_settings_.VP9()->numberOfTemporalLayers = num_temporal_layers_;
|
codec_settings_.VP9()->numberOfTemporalLayers = num_temporal_layers_;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
GofInfoVP9 gof;
|
GofInfoVP9 gof;
|
||||||
if (num_temporal_layers_ == 1) {
|
if (num_temporal_layers_ == 1) {
|
||||||
@ -1234,8 +1218,7 @@ TEST_P(TestVp9ImplWithLayering, ExternalRefControl) {
|
|||||||
codec_settings_.VP9()->numberOfSpatialLayers = num_spatial_layers_;
|
codec_settings_.VP9()->numberOfSpatialLayers = num_spatial_layers_;
|
||||||
codec_settings_.VP9()->numberOfTemporalLayers = num_temporal_layers_;
|
codec_settings_.VP9()->numberOfTemporalLayers = num_temporal_layers_;
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
GofInfoVP9 gof;
|
GofInfoVP9 gof;
|
||||||
if (num_temporal_layers_ == 1) {
|
if (num_temporal_layers_ == 1) {
|
||||||
@ -1291,8 +1274,7 @@ TEST_F(TestVp9ImplFrameDropping, PreEncodeFrameDropping) {
|
|||||||
|
|
||||||
codec_settings_.maxFramerate = static_cast<uint32_t>(expected_framerate_fps);
|
codec_settings_.maxFramerate = static_cast<uint32_t>(expected_framerate_fps);
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
VideoFrame* input_frame = NextInputFrame();
|
VideoFrame* input_frame = NextInputFrame();
|
||||||
for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
|
for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
|
||||||
@ -1341,8 +1323,7 @@ TEST_F(TestVp9ImplFrameDropping, DifferentFrameratePerSpatialLayer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||||
encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
|
encoder_->InitEncode(&codec_settings_, kSettings));
|
||||||
0 /* max payload size (unused) */));
|
|
||||||
|
|
||||||
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
encoder_->SetRates(VideoEncoder::RateControlParameters(
|
||||||
bitrate_allocation, codec_settings_.maxFramerate));
|
bitrate_allocation, codec_settings_.maxFramerate));
|
||||||
|
|||||||
@ -401,9 +401,16 @@ void VP9EncoderImpl::SetRates(const RateControlParameters& parameters) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
|
int VP9EncoderImpl::InitEncode(const VideoCodec* codec_settings,
|
||||||
int number_of_cores,
|
int number_of_cores,
|
||||||
size_t /*max_payload_size*/) {
|
size_t max_payload_size) {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(eladalon): s/inst/codec_settings/g.
|
||||||
|
int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
|
||||||
|
const Settings& settings) {
|
||||||
if (inst == nullptr) {
|
if (inst == nullptr) {
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
||||||
}
|
}
|
||||||
@ -417,7 +424,7 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
|
|||||||
if (inst->width < 1 || inst->height < 1) {
|
if (inst->width < 1 || inst->height < 1) {
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
||||||
}
|
}
|
||||||
if (number_of_cores < 1) {
|
if (settings.number_of_cores < 1) {
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
||||||
}
|
}
|
||||||
if (inst->VP9().numberOfTemporalLayers > 3) {
|
if (inst->VP9().numberOfTemporalLayers > 3) {
|
||||||
@ -526,7 +533,7 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
|
|||||||
config_->rc_resize_allowed = inst->VP9().automaticResizeOn ? 1 : 0;
|
config_->rc_resize_allowed = inst->VP9().automaticResizeOn ? 1 : 0;
|
||||||
// Determine number of threads based on the image size and #cores.
|
// Determine number of threads based on the image size and #cores.
|
||||||
config_->g_threads =
|
config_->g_threads =
|
||||||
NumberOfThreads(config_->g_w, config_->g_h, number_of_cores);
|
NumberOfThreads(config_->g_w, config_->g_h, settings.number_of_cores);
|
||||||
|
|
||||||
cpu_speed_ = GetCpuSpeed(config_->g_w, config_->g_h);
|
cpu_speed_ = GetCpuSpeed(config_->g_w, config_->g_h);
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "modules/video_coding/codecs/vp9/include/vp9.h"
|
#include "modules/video_coding/codecs/vp9/include/vp9.h"
|
||||||
|
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "media/base/vp9_profile.h"
|
#include "media/base/vp9_profile.h"
|
||||||
#include "modules/video_coding/codecs/vp9/vp9_frame_buffer_pool.h"
|
#include "modules/video_coding/codecs/vp9/vp9_frame_buffer_pool.h"
|
||||||
#include "modules/video_coding/utility/framerate_controller.h"
|
#include "modules/video_coding/utility/framerate_controller.h"
|
||||||
@ -42,6 +43,8 @@ class VP9EncoderImpl : public VP9Encoder {
|
|||||||
int InitEncode(const VideoCodec* codec_settings,
|
int InitEncode(const VideoCodec* codec_settings,
|
||||||
int number_of_cores,
|
int number_of_cores,
|
||||||
size_t max_payload_size) override;
|
size_t max_payload_size) override;
|
||||||
|
int InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const Settings& settings) override;
|
||||||
|
|
||||||
int Encode(const VideoFrame& input_image,
|
int Encode(const VideoFrame& input_image,
|
||||||
const std::vector<VideoFrameType>* frame_types) override;
|
const std::vector<VideoFrameType>* frame_types) override;
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "api/video/encoded_image.h"
|
#include "api/video/encoded_image.h"
|
||||||
#include "api/video_codecs/sdp_video_format.h"
|
#include "api/video_codecs/sdp_video_format.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "common_video/libyuv/include/webrtc_libyuv.h"
|
#include "common_video/libyuv/include/webrtc_libyuv.h"
|
||||||
#include "modules/video_coding/include/video_codec_interface.h"
|
#include "modules/video_coding/include/video_codec_interface.h"
|
||||||
#include "modules/video_coding/include/video_coding_defines.h"
|
#include "modules/video_coding/include/video_coding_defines.h"
|
||||||
@ -46,6 +47,9 @@ const int kTargetBitrates[kNumberOfSimulcastStreams] = {100, 450, 1000};
|
|||||||
const int kDefaultTemporalLayerProfile[3] = {3, 3, 3};
|
const int kDefaultTemporalLayerProfile[3] = {3, 3, 3};
|
||||||
const int kNoTemporalLayerProfile[3] = {0, 0, 0};
|
const int kNoTemporalLayerProfile[3] = {0, 0, 0};
|
||||||
|
|
||||||
|
const VideoEncoder::Capabilities kCapabilities(false);
|
||||||
|
const VideoEncoder::Settings kSettings(kCapabilities, 1, 1200);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void SetExpectedValues3(T value0, T value1, T value2, T* expected_values) {
|
void SetExpectedValues3(T value0, T value1, T value2, T* expected_values) {
|
||||||
expected_values[0] = value0;
|
expected_values[0] = value0;
|
||||||
@ -271,7 +275,7 @@ void SimulcastTestFixtureImpl::SetUpCodec(const int* temporal_layer_profile) {
|
|||||||
decoder_->RegisterDecodeCompleteCallback(&decoder_callback_);
|
decoder_->RegisterDecodeCompleteCallback(&decoder_callback_);
|
||||||
DefaultSettings(&settings_, temporal_layer_profile, codec_type_);
|
DefaultSettings(&settings_, temporal_layer_profile, codec_type_);
|
||||||
SetUpRateAllocator();
|
SetUpRateAllocator();
|
||||||
EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200));
|
EXPECT_EQ(0, encoder_->InitEncode(&settings_, kSettings));
|
||||||
EXPECT_EQ(0, decoder_->InitDecode(&settings_, 1));
|
EXPECT_EQ(0, decoder_->InitDecode(&settings_, 1));
|
||||||
input_buffer_ = I420Buffer::Create(kDefaultWidth, kDefaultHeight);
|
input_buffer_ = I420Buffer::Create(kDefaultWidth, kDefaultHeight);
|
||||||
input_buffer_->InitializeData();
|
input_buffer_->InitializeData();
|
||||||
@ -323,7 +327,7 @@ void SimulcastTestFixtureImpl::UpdateActiveStreams(
|
|||||||
// allocator has support for updating active streams without a
|
// allocator has support for updating active streams without a
|
||||||
// reinitialization, we can just call that here instead.
|
// reinitialization, we can just call that here instead.
|
||||||
SetUpRateAllocator();
|
SetUpRateAllocator();
|
||||||
EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200));
|
EXPECT_EQ(0, encoder_->InitEncode(&settings_, kSettings));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimulcastTestFixtureImpl::ExpectStreams(
|
void SimulcastTestFixtureImpl::ExpectStreams(
|
||||||
@ -617,7 +621,7 @@ void SimulcastTestFixtureImpl::SwitchingToOneStream(int width, int height) {
|
|||||||
settings_.simulcastStream[settings_.numberOfSimulcastStreams - 1].height =
|
settings_.simulcastStream[settings_.numberOfSimulcastStreams - 1].height =
|
||||||
settings_.height;
|
settings_.height;
|
||||||
SetUpRateAllocator();
|
SetUpRateAllocator();
|
||||||
EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200));
|
EXPECT_EQ(0, encoder_->InitEncode(&settings_, kSettings));
|
||||||
|
|
||||||
// Encode one frame and verify.
|
// Encode one frame and verify.
|
||||||
SetRates(kMaxBitrates[0] + kMaxBitrates[1], 30);
|
SetRates(kMaxBitrates[0] + kMaxBitrates[1], 30);
|
||||||
@ -640,7 +644,7 @@ void SimulcastTestFixtureImpl::SwitchingToOneStream(int width, int height) {
|
|||||||
// Start at the lowest bitrate for enabling base stream.
|
// Start at the lowest bitrate for enabling base stream.
|
||||||
settings_.startBitrate = kMinBitrates[0];
|
settings_.startBitrate = kMinBitrates[0];
|
||||||
SetUpRateAllocator();
|
SetUpRateAllocator();
|
||||||
EXPECT_EQ(0, encoder_->InitEncode(&settings_, 1, 1200));
|
EXPECT_EQ(0, encoder_->InitEncode(&settings_, kSettings));
|
||||||
SetRates(settings_.startBitrate, 30);
|
SetRates(settings_.startBitrate, 30);
|
||||||
ExpectStreams(VideoFrameType::kVideoFrameKey, 1);
|
ExpectStreams(VideoFrameType::kVideoFrameKey, 1);
|
||||||
// Resize |input_frame_| to the new resolution.
|
// Resize |input_frame_| to the new resolution.
|
||||||
|
|||||||
@ -710,6 +710,7 @@ if (is_android) {
|
|||||||
"../../rtc_base:checks",
|
"../../rtc_base:checks",
|
||||||
"../../rtc_base:rtc_task_queue",
|
"../../rtc_base:rtc_task_queue",
|
||||||
"../../rtc_base/task_utils:to_queued_task",
|
"../../rtc_base/task_utils:to_queued_task",
|
||||||
|
"//third_party/abseil-cpp/absl/types:optional",
|
||||||
"//third_party/libyuv",
|
"//third_party/libyuv",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,10 +28,19 @@ public interface VideoEncoder {
|
|||||||
public final int maxFramerate;
|
public final int maxFramerate;
|
||||||
public final int numberOfSimulcastStreams;
|
public final int numberOfSimulcastStreams;
|
||||||
public final boolean automaticResizeOn;
|
public final boolean automaticResizeOn;
|
||||||
|
public final Capabilities capabilities;
|
||||||
|
|
||||||
|
// TODO(bugs.webrtc.org/10720): Remove.
|
||||||
|
@Deprecated
|
||||||
|
public Settings(int numberOfCores, int width, int height, int startBitrate, int maxFramerate,
|
||||||
|
int numberOfSimulcastStreams, boolean automaticResizeOn) {
|
||||||
|
this(numberOfCores, width, height, startBitrate, maxFramerate, numberOfSimulcastStreams,
|
||||||
|
automaticResizeOn, new VideoEncoder.Capabilities(false /* lossNotification */));
|
||||||
|
}
|
||||||
|
|
||||||
@CalledByNative("Settings")
|
@CalledByNative("Settings")
|
||||||
public Settings(int numberOfCores, int width, int height, int startBitrate, int maxFramerate,
|
public Settings(int numberOfCores, int width, int height, int startBitrate, int maxFramerate,
|
||||||
int numberOfSimulcastStreams, boolean automaticResizeOn) {
|
int numberOfSimulcastStreams, boolean automaticResizeOn, Capabilities capabilities) {
|
||||||
this.numberOfCores = numberOfCores;
|
this.numberOfCores = numberOfCores;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
@ -39,6 +48,21 @@ public interface VideoEncoder {
|
|||||||
this.maxFramerate = maxFramerate;
|
this.maxFramerate = maxFramerate;
|
||||||
this.numberOfSimulcastStreams = numberOfSimulcastStreams;
|
this.numberOfSimulcastStreams = numberOfSimulcastStreams;
|
||||||
this.automaticResizeOn = automaticResizeOn;
|
this.automaticResizeOn = automaticResizeOn;
|
||||||
|
this.capabilities = capabilities;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Capabilities (loss notification, etc.) passed to the encoder by WebRTC. */
|
||||||
|
public class Capabilities {
|
||||||
|
/**
|
||||||
|
* The remote side has support for the loss notification RTCP feedback message format, and will
|
||||||
|
* be sending these feedback messages if necessary.
|
||||||
|
*/
|
||||||
|
public final boolean lossNotification;
|
||||||
|
|
||||||
|
@CalledByNative("Capabilities")
|
||||||
|
public Capabilities(boolean lossNotification) {
|
||||||
|
this.lossNotification = lossNotification;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -76,7 +76,8 @@ public final class AndroidVideoDecoderInstrumentationTest {
|
|||||||
private static final boolean ENABLE_H264_HIGH_PROFILE = true;
|
private static final boolean ENABLE_H264_HIGH_PROFILE = true;
|
||||||
private static final VideoEncoder.Settings ENCODER_SETTINGS =
|
private static final VideoEncoder.Settings ENCODER_SETTINGS =
|
||||||
new VideoEncoder.Settings(1 /* core */, TEST_FRAME_WIDTH, TEST_FRAME_HEIGHT, 300 /* kbps */,
|
new VideoEncoder.Settings(1 /* core */, TEST_FRAME_WIDTH, TEST_FRAME_HEIGHT, 300 /* kbps */,
|
||||||
30 /* fps */, 1 /* numberOfSimulcastStreams */, true /* automaticResizeOn */);
|
30 /* fps */, 1 /* numberOfSimulcastStreams */, true /* automaticResizeOn */,
|
||||||
|
/* capabilities= */ new VideoEncoder.Capabilities(false /* lossNotification */));
|
||||||
|
|
||||||
private static final int DECODE_TIMEOUT_MS = 1000;
|
private static final int DECODE_TIMEOUT_MS = 1000;
|
||||||
private static final VideoDecoder.Settings SETTINGS =
|
private static final VideoDecoder.Settings SETTINGS =
|
||||||
|
|||||||
@ -70,7 +70,8 @@ public class HardwareVideoEncoderTest {
|
|||||||
private static final boolean ENABLE_H264_HIGH_PROFILE = true;
|
private static final boolean ENABLE_H264_HIGH_PROFILE = true;
|
||||||
private static final VideoEncoder.Settings SETTINGS =
|
private static final VideoEncoder.Settings SETTINGS =
|
||||||
new VideoEncoder.Settings(1 /* core */, 640 /* width */, 480 /* height */, 300 /* kbps */,
|
new VideoEncoder.Settings(1 /* core */, 640 /* width */, 480 /* height */, 300 /* kbps */,
|
||||||
30 /* fps */, 1 /* numberOfSimulcastStreams */, true /* automaticResizeOn */);
|
30 /* fps */, 1 /* numberOfSimulcastStreams */, true /* automaticResizeOn */,
|
||||||
|
/* capabilities= */ new VideoEncoder.Capabilities(false /* lossNotification */));
|
||||||
private static final int ENCODE_TIMEOUT_MS = 1000;
|
private static final int ENCODE_TIMEOUT_MS = 1000;
|
||||||
private static final int NUM_TEST_FRAMES = 10;
|
private static final int NUM_TEST_FRAMES = 10;
|
||||||
private static final int NUM_ENCODE_TRIES = 100;
|
private static final int NUM_ENCODE_TRIES = 100;
|
||||||
|
|||||||
@ -99,6 +99,8 @@ class MediaCodecVideoEncoder : public VideoEncoder {
|
|||||||
int32_t InitEncode(const VideoCodec* codec_settings,
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
int32_t /* number_of_cores */,
|
int32_t /* number_of_cores */,
|
||||||
size_t /* max_payload_size */) override;
|
size_t /* max_payload_size */) override;
|
||||||
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const Settings& settings) override;
|
||||||
int32_t Encode(const VideoFrame& input_image,
|
int32_t Encode(const VideoFrame& input_image,
|
||||||
const std::vector<VideoFrameType>* frame_types) override;
|
const std::vector<VideoFrameType>* frame_types) override;
|
||||||
int32_t RegisterEncodeCompleteCallback(
|
int32_t RegisterEncodeCompleteCallback(
|
||||||
@ -306,6 +308,12 @@ MediaCodecVideoEncoder::MediaCodecVideoEncoder(JNIEnv* jni,
|
|||||||
int32_t MediaCodecVideoEncoder::InitEncode(const VideoCodec* codec_settings,
|
int32_t MediaCodecVideoEncoder::InitEncode(const VideoCodec* codec_settings,
|
||||||
int32_t /* number_of_cores */,
|
int32_t /* number_of_cores */,
|
||||||
size_t /* max_payload_size */) {
|
size_t /* max_payload_size */) {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t MediaCodecVideoEncoder::InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const Settings& settings) {
|
||||||
RTC_DCHECK_RUN_ON(&encoder_queue_checker_);
|
RTC_DCHECK_RUN_ON(&encoder_queue_checker_);
|
||||||
if (codec_settings == NULL) {
|
if (codec_settings == NULL) {
|
||||||
ALOGE << "NULL VideoCodec instance";
|
ALOGE << "NULL VideoCodec instance";
|
||||||
|
|||||||
@ -41,10 +41,17 @@ VideoEncoderWrapper::~VideoEncoderWrapper() = default;
|
|||||||
int32_t VideoEncoderWrapper::InitEncode(const VideoCodec* codec_settings,
|
int32_t VideoEncoderWrapper::InitEncode(const VideoCodec* codec_settings,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) {
|
size_t max_payload_size) {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int VideoEncoderWrapper::InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const Settings& settings) {
|
||||||
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||||
|
|
||||||
number_of_cores_ = number_of_cores;
|
|
||||||
codec_settings_ = *codec_settings;
|
codec_settings_ = *codec_settings;
|
||||||
|
capabilities_ = settings.capabilities;
|
||||||
|
number_of_cores_ = settings.number_of_cores;
|
||||||
num_resets_ = 0;
|
num_resets_ = 0;
|
||||||
{
|
{
|
||||||
rtc::CritScope lock(&encoder_queue_crit_);
|
rtc::CritScope lock(&encoder_queue_crit_);
|
||||||
@ -69,12 +76,16 @@ int32_t VideoEncoderWrapper::InitEncodeInternal(JNIEnv* jni) {
|
|||||||
automatic_resize_on = true;
|
automatic_resize_on = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RTC_DCHECK(capabilities_);
|
||||||
|
ScopedJavaLocalRef<jobject> capabilities =
|
||||||
|
Java_Capabilities_Constructor(jni, capabilities_->loss_notification);
|
||||||
|
|
||||||
ScopedJavaLocalRef<jobject> settings = Java_Settings_Constructor(
|
ScopedJavaLocalRef<jobject> settings = Java_Settings_Constructor(
|
||||||
jni, number_of_cores_, codec_settings_.width, codec_settings_.height,
|
jni, number_of_cores_, codec_settings_.width, codec_settings_.height,
|
||||||
static_cast<int>(codec_settings_.startBitrate),
|
static_cast<int>(codec_settings_.startBitrate),
|
||||||
static_cast<int>(codec_settings_.maxFramerate),
|
static_cast<int>(codec_settings_.maxFramerate),
|
||||||
static_cast<int>(codec_settings_.numberOfSimulcastStreams),
|
static_cast<int>(codec_settings_.numberOfSimulcastStreams),
|
||||||
automatic_resize_on);
|
automatic_resize_on, capabilities);
|
||||||
|
|
||||||
ScopedJavaLocalRef<jobject> callback =
|
ScopedJavaLocalRef<jobject> callback =
|
||||||
Java_VideoEncoderWrapper_createEncoderCallback(jni,
|
Java_VideoEncoderWrapper_createEncoderCallback(jni,
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "absl/types/optional.h"
|
||||||
#include "api/task_queue/task_queue_base.h"
|
#include "api/task_queue/task_queue_base.h"
|
||||||
#include "api/video_codecs/video_encoder.h"
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "common_video/h264/h264_bitstream_parser.h"
|
#include "common_video/h264/h264_bitstream_parser.h"
|
||||||
@ -35,6 +36,8 @@ class VideoEncoderWrapper : public VideoEncoder {
|
|||||||
int32_t InitEncode(const VideoCodec* codec_settings,
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override;
|
size_t max_payload_size) override;
|
||||||
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const Settings& settings) override;
|
||||||
|
|
||||||
int32_t RegisterEncodeCompleteCallback(
|
int32_t RegisterEncodeCompleteCallback(
|
||||||
EncodedImageCallback* callback) override;
|
EncodedImageCallback* callback) override;
|
||||||
@ -95,6 +98,7 @@ class VideoEncoderWrapper : public VideoEncoder {
|
|||||||
EncodedImageCallback* callback_;
|
EncodedImageCallback* callback_;
|
||||||
bool initialized_;
|
bool initialized_;
|
||||||
int num_resets_;
|
int num_resets_;
|
||||||
|
absl::optional<VideoEncoder::Capabilities> capabilities_;
|
||||||
int number_of_cores_;
|
int number_of_cores_;
|
||||||
VideoCodec codec_settings_;
|
VideoCodec codec_settings_;
|
||||||
EncoderInfo encoder_info_;
|
EncoderInfo encoder_info_;
|
||||||
|
|||||||
@ -58,7 +58,8 @@ public class HardwareVideoEncoderTest {
|
|||||||
/* startBitrate= */ 10000,
|
/* startBitrate= */ 10000,
|
||||||
/* maxFramerate= */ 30,
|
/* maxFramerate= */ 30,
|
||||||
/* numberOfSimulcastStreams= */ 1,
|
/* numberOfSimulcastStreams= */ 1,
|
||||||
/* automaticResizeOn= */ true);
|
/* automaticResizeOn= */ true,
|
||||||
|
/* capabilities= */ new VideoEncoder.Capabilities(false /* lossNotification */));
|
||||||
private static final long POLL_DELAY_MS = 10;
|
private static final long POLL_DELAY_MS = 10;
|
||||||
private static final long DELIVER_ENCODED_IMAGE_DELAY_MS = 10;
|
private static final long DELIVER_ENCODED_IMAGE_DELAY_MS = 10;
|
||||||
|
|
||||||
|
|||||||
@ -44,9 +44,15 @@ class ObjCVideoEncoder : public VideoEncoder {
|
|||||||
int32_t InitEncode(const VideoCodec *codec_settings,
|
int32_t InitEncode(const VideoCodec *codec_settings,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override {
|
size_t max_payload_size) override {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec *codec_settings, const Settings &encoder_settings) override {
|
||||||
RTCVideoEncoderSettings *settings =
|
RTCVideoEncoderSettings *settings =
|
||||||
[[RTCVideoEncoderSettings alloc] initWithNativeVideoCodec:codec_settings];
|
[[RTCVideoEncoderSettings alloc] initWithNativeVideoCodec:codec_settings];
|
||||||
return [encoder_ startEncodeWithSettings:settings numberOfCores:number_of_cores];
|
return [encoder_ startEncodeWithSettings:settings
|
||||||
|
numberOfCores:encoder_settings.number_of_cores];
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t RegisterEncodeCompleteCallback(EncodedImageCallback *callback) override {
|
int32_t RegisterEncodeCompleteCallback(EncodedImageCallback *callback) override {
|
||||||
|
|||||||
@ -13,12 +13,12 @@
|
|||||||
|
|
||||||
#include "sdk/objc/native/src/objc_video_encoder_factory.h"
|
#include "sdk/objc/native/src/objc_video_encoder_factory.h"
|
||||||
|
|
||||||
|
#include "api/video_codecs/sdp_video_format.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#import "base/RTCVideoEncoder.h"
|
#import "base/RTCVideoEncoder.h"
|
||||||
#import "base/RTCVideoEncoderFactory.h"
|
#import "base/RTCVideoEncoderFactory.h"
|
||||||
#import "base/RTCVideoFrameBuffer.h"
|
#import "base/RTCVideoFrameBuffer.h"
|
||||||
#import "components/video_frame_buffer/RTCCVPixelBuffer.h"
|
#import "components/video_frame_buffer/RTCCVPixelBuffer.h"
|
||||||
|
|
||||||
#include "api/video_codecs/sdp_video_format.h"
|
|
||||||
#include "modules/include/module_common_types.h"
|
#include "modules/include/module_common_types.h"
|
||||||
#include "modules/video_coding/include/video_codec_interface.h"
|
#include "modules/video_coding/include/video_codec_interface.h"
|
||||||
#include "modules/video_coding/include/video_error_codes.h"
|
#include "modules/video_coding/include/video_error_codes.h"
|
||||||
@ -61,14 +61,18 @@ TEST(ObjCVideoEncoderFactoryTest, InitEncodeReturnsOKOnSuccess) {
|
|||||||
std::unique_ptr<webrtc::VideoEncoder> encoder = GetObjCEncoder(CreateOKEncoderFactory());
|
std::unique_ptr<webrtc::VideoEncoder> encoder = GetObjCEncoder(CreateOKEncoderFactory());
|
||||||
|
|
||||||
auto* settings = new webrtc::VideoCodec();
|
auto* settings = new webrtc::VideoCodec();
|
||||||
EXPECT_EQ(encoder->InitEncode(settings, 1, 0), WEBRTC_VIDEO_CODEC_OK);
|
const webrtc::VideoEncoder::Capabilities kCapabilities(false);
|
||||||
|
EXPECT_EQ(encoder->InitEncode(settings, webrtc::VideoEncoder::Settings(kCapabilities, 1, 0)),
|
||||||
|
WEBRTC_VIDEO_CODEC_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ObjCVideoEncoderFactoryTest, InitEncodeReturnsErrorOnFail) {
|
TEST(ObjCVideoEncoderFactoryTest, InitEncodeReturnsErrorOnFail) {
|
||||||
std::unique_ptr<webrtc::VideoEncoder> encoder = GetObjCEncoder(CreateErrorEncoderFactory());
|
std::unique_ptr<webrtc::VideoEncoder> encoder = GetObjCEncoder(CreateErrorEncoderFactory());
|
||||||
|
|
||||||
auto* settings = new webrtc::VideoCodec();
|
auto* settings = new webrtc::VideoCodec();
|
||||||
EXPECT_EQ(encoder->InitEncode(settings, 1, 0), WEBRTC_VIDEO_CODEC_ERROR);
|
const webrtc::VideoEncoder::Capabilities kCapabilities(false);
|
||||||
|
EXPECT_EQ(encoder->InitEncode(settings, webrtc::VideoEncoder::Settings(kCapabilities, 1, 0)),
|
||||||
|
WEBRTC_VIDEO_CODEC_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ObjCVideoEncoderFactoryTest, EncodeReturnsOKOnSuccess) {
|
TEST(ObjCVideoEncoderFactoryTest, EncodeReturnsOKOnSuccess) {
|
||||||
|
|||||||
@ -40,6 +40,13 @@ int32_t ConfigurableFrameSizeEncoder::InitEncode(
|
|||||||
const VideoCodec* codec_settings,
|
const VideoCodec* codec_settings,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) {
|
size_t max_payload_size) {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ConfigurableFrameSizeEncoder::InitEncode(
|
||||||
|
const VideoCodec* codec_settings,
|
||||||
|
const Settings& settings) {
|
||||||
return WEBRTC_VIDEO_CODEC_OK;
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,6 +35,8 @@ class ConfigurableFrameSizeEncoder : public VideoEncoder {
|
|||||||
int32_t InitEncode(const VideoCodec* codec_settings,
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override;
|
size_t max_payload_size) override;
|
||||||
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const Settings& settings) override;
|
||||||
|
|
||||||
int32_t Encode(const VideoFrame& input_image,
|
int32_t Encode(const VideoFrame& input_image,
|
||||||
const std::vector<VideoFrameType>* frame_types) override;
|
const std::vector<VideoFrameType>* frame_types) override;
|
||||||
|
|||||||
@ -70,6 +70,12 @@ void FakeEncoder::SetMaxBitrate(int max_kbps) {
|
|||||||
int32_t FakeEncoder::InitEncode(const VideoCodec* config,
|
int32_t FakeEncoder::InitEncode(const VideoCodec* config,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) {
|
size_t max_payload_size) {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t FakeEncoder::InitEncode(const VideoCodec* config,
|
||||||
|
const Settings& settings) {
|
||||||
rtc::CritScope cs(&crit_sect_);
|
rtc::CritScope cs(&crit_sect_);
|
||||||
config_ = *config;
|
config_ = *config;
|
||||||
current_rate_settings_.bitrate.SetBitrate(0, 0, config_.startBitrate * 1000);
|
current_rate_settings_.bitrate.SetBitrate(0, 0, config_.startBitrate * 1000);
|
||||||
@ -366,6 +372,12 @@ MultithreadedFakeH264Encoder::MultithreadedFakeH264Encoder(
|
|||||||
int32_t MultithreadedFakeH264Encoder::InitEncode(const VideoCodec* config,
|
int32_t MultithreadedFakeH264Encoder::InitEncode(const VideoCodec* config,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) {
|
size_t max_payload_size) {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t MultithreadedFakeH264Encoder::InitEncode(const VideoCodec* config,
|
||||||
|
const Settings& settings) {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
|
||||||
queue1_ = task_queue_factory_->CreateTaskQueue(
|
queue1_ = task_queue_factory_->CreateTaskQueue(
|
||||||
@ -373,7 +385,7 @@ int32_t MultithreadedFakeH264Encoder::InitEncode(const VideoCodec* config,
|
|||||||
queue2_ = task_queue_factory_->CreateTaskQueue(
|
queue2_ = task_queue_factory_->CreateTaskQueue(
|
||||||
"Queue 2", TaskQueueFactory::Priority::NORMAL);
|
"Queue 2", TaskQueueFactory::Priority::NORMAL);
|
||||||
|
|
||||||
return FakeH264Encoder::InitEncode(config, number_of_cores, max_payload_size);
|
return FakeH264Encoder::InitEncode(config, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultithreadedFakeH264Encoder::EncodeTask : public QueuedTask {
|
class MultithreadedFakeH264Encoder::EncodeTask : public QueuedTask {
|
||||||
|
|||||||
@ -43,6 +43,8 @@ class FakeEncoder : public VideoEncoder {
|
|||||||
int32_t InitEncode(const VideoCodec* config,
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override;
|
size_t max_payload_size) override;
|
||||||
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
|
const Settings& settings) override;
|
||||||
int32_t Encode(const VideoFrame& input_image,
|
int32_t Encode(const VideoFrame& input_image,
|
||||||
const std::vector<VideoFrameType>* frame_types) override;
|
const std::vector<VideoFrameType>* frame_types) override;
|
||||||
int32_t RegisterEncodeCompleteCallback(
|
int32_t RegisterEncodeCompleteCallback(
|
||||||
@ -141,6 +143,8 @@ class MultithreadedFakeH264Encoder : public test::FakeH264Encoder {
|
|||||||
int32_t InitEncode(const VideoCodec* config,
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override;
|
size_t max_payload_size) override;
|
||||||
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
|
const Settings& settings) override;
|
||||||
|
|
||||||
int32_t Encode(const VideoFrame& input_image,
|
int32_t Encode(const VideoFrame& input_image,
|
||||||
const std::vector<VideoFrameType>* frame_types) override;
|
const std::vector<VideoFrameType>* frame_types) override;
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||||
#include "api/video_codecs/vp8_temporal_layers_factory.h"
|
#include "api/video_codecs/vp8_temporal_layers_factory.h"
|
||||||
#include "modules/video_coding/codecs/interface/common_constants.h"
|
#include "modules/video_coding/codecs/interface/common_constants.h"
|
||||||
@ -51,9 +52,14 @@ FakeVP8Encoder::FakeVP8Encoder(Clock* clock) : FakeEncoder(clock) {
|
|||||||
int32_t FakeVP8Encoder::InitEncode(const VideoCodec* config,
|
int32_t FakeVP8Encoder::InitEncode(const VideoCodec* config,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) {
|
size_t max_payload_size) {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t FakeVP8Encoder::InitEncode(const VideoCodec* config,
|
||||||
|
const Settings& settings) {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
auto result =
|
auto result = FakeEncoder::InitEncode(config, settings);
|
||||||
FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
|
|
||||||
if (result != WEBRTC_VIDEO_CODEC_OK) {
|
if (result != WEBRTC_VIDEO_CODEC_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,6 +40,9 @@ class FakeVP8Encoder : public FakeEncoder {
|
|||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override;
|
size_t max_payload_size) override;
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
|
const Settings& settings) override;
|
||||||
|
|
||||||
int32_t Release() override;
|
int32_t Release() override;
|
||||||
|
|
||||||
EncoderInfo GetEncoderInfo() const override;
|
EncoderInfo GetEncoderInfo() const override;
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "api/video/video_codec_type.h"
|
#include "api/video/video_codec_type.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "modules/video_coding/include/video_error_codes.h"
|
#include "modules/video_coding/include/video_error_codes.h"
|
||||||
#include "rtc_base/critical_section.h"
|
#include "rtc_base/critical_section.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
@ -72,6 +73,13 @@ int32_t QualityAnalyzingVideoEncoder::InitEncode(
|
|||||||
const VideoCodec* codec_settings,
|
const VideoCodec* codec_settings,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) {
|
size_t max_payload_size) {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t QualityAnalyzingVideoEncoder::InitEncode(
|
||||||
|
const VideoCodec* codec_settings,
|
||||||
|
const Settings& settings) {
|
||||||
rtc::CritScope crit(&lock_);
|
rtc::CritScope crit(&lock_);
|
||||||
codec_settings_ = *codec_settings;
|
codec_settings_ = *codec_settings;
|
||||||
mode_ = SimulcastMode::kNormal;
|
mode_ = SimulcastMode::kNormal;
|
||||||
@ -96,8 +104,7 @@ int32_t QualityAnalyzingVideoEncoder::InitEncode(
|
|||||||
if (codec_settings->numberOfSimulcastStreams > 1) {
|
if (codec_settings->numberOfSimulcastStreams > 1) {
|
||||||
mode_ = SimulcastMode::kSimulcast;
|
mode_ = SimulcastMode::kSimulcast;
|
||||||
}
|
}
|
||||||
return delegate_->InitEncode(codec_settings, number_of_cores,
|
return delegate_->InitEncode(codec_settings, settings);
|
||||||
max_payload_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t QualityAnalyzingVideoEncoder::RegisterEncodeCompleteCallback(
|
int32_t QualityAnalyzingVideoEncoder::RegisterEncodeCompleteCallback(
|
||||||
|
|||||||
@ -65,6 +65,8 @@ class QualityAnalyzingVideoEncoder : public VideoEncoder,
|
|||||||
int32_t InitEncode(const VideoCodec* codec_settings,
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override;
|
size_t max_payload_size) override;
|
||||||
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const Settings& settings) override;
|
||||||
int32_t RegisterEncodeCompleteCallback(
|
int32_t RegisterEncodeCompleteCallback(
|
||||||
EncodedImageCallback* callback) override;
|
EncodedImageCallback* callback) override;
|
||||||
int32_t Release() override;
|
int32_t Release() override;
|
||||||
|
|||||||
@ -21,6 +21,10 @@
|
|||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace test {
|
namespace test {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const VideoEncoder::Capabilities kCapabilities(false);
|
||||||
|
}
|
||||||
|
|
||||||
// An encoder factory with a single underlying VideoEncoder object,
|
// An encoder factory with a single underlying VideoEncoder object,
|
||||||
// intended for test purposes. Each call to CreateVideoEncoder returns
|
// intended for test purposes. Each call to CreateVideoEncoder returns
|
||||||
// a proxy for the same encoder, typically an instance of FakeEncoder.
|
// a proxy for the same encoder, typically an instance of FakeEncoder.
|
||||||
@ -68,7 +72,12 @@ class VideoEncoderProxyFactory final : public VideoEncoderFactory {
|
|||||||
int32_t InitEncode(const VideoCodec* config,
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override {
|
size_t max_payload_size) override {
|
||||||
return encoder_->InitEncode(config, number_of_cores, max_payload_size);
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
|
const Settings& settings) override {
|
||||||
|
return encoder_->InitEncode(config, settings);
|
||||||
}
|
}
|
||||||
int32_t RegisterEncodeCompleteCallback(
|
int32_t RegisterEncodeCompleteCallback(
|
||||||
EncodedImageCallback* callback) override {
|
EncodedImageCallback* callback) override {
|
||||||
|
|||||||
@ -262,6 +262,7 @@ if (rtc_include_tests) {
|
|||||||
"../api/video:video_bitrate_allocator_factory",
|
"../api/video:video_bitrate_allocator_factory",
|
||||||
"../api/video:video_frame",
|
"../api/video:video_frame",
|
||||||
"../api/video:video_rtp_headers",
|
"../api/video:video_rtp_headers",
|
||||||
|
"../api/video_codecs:video_codecs_api",
|
||||||
"../call:fake_network",
|
"../call:fake_network",
|
||||||
"../call:simulated_network",
|
"../call:simulated_network",
|
||||||
"../common_video",
|
"../common_video",
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "api/test/simulated_network.h"
|
#include "api/test/simulated_network.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "call/fake_network_pipe.h"
|
#include "call/fake_network_pipe.h"
|
||||||
#include "call/simulated_network.h"
|
#include "call/simulated_network.h"
|
||||||
#include "system_wrappers/include/sleep.h"
|
#include "system_wrappers/include/sleep.h"
|
||||||
@ -358,6 +359,12 @@ TEST_F(NetworkStateEndToEndTest, NewVideoSendStreamsRespectVideoNetworkDown) {
|
|||||||
int32_t InitEncode(const VideoCodec* config,
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override {
|
size_t max_payload_size) override {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
|
const Settings& settings) override {
|
||||||
EXPECT_GT(config->startBitrate, 0u);
|
EXPECT_GT(config->startBitrate, 0u);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#include "api/rtc_event_log_output_file.h"
|
#include "api/rtc_event_log_output_file.h"
|
||||||
#include "api/task_queue/default_task_queue_factory.h"
|
#include "api/task_queue/default_task_queue_factory.h"
|
||||||
#include "api/video/builtin_video_bitrate_allocator_factory.h"
|
#include "api/video/builtin_video_bitrate_allocator_factory.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "call/fake_network_pipe.h"
|
#include "call/fake_network_pipe.h"
|
||||||
#include "call/simulated_network.h"
|
#include "call/simulated_network.h"
|
||||||
#include "media/engine/adm_helpers.h"
|
#include "media/engine/adm_helpers.h"
|
||||||
@ -67,6 +68,8 @@ constexpr uint32_t kThumbnailRtxSsrcStart = 0xF0000;
|
|||||||
|
|
||||||
constexpr int kDefaultMaxQp = cricket::WebRtcVideoChannel::kDefaultQpMax;
|
constexpr int kDefaultMaxQp = cricket::WebRtcVideoChannel::kDefaultQpMax;
|
||||||
|
|
||||||
|
const VideoEncoder::Capabilities kCapabilities(false);
|
||||||
|
|
||||||
std::pair<uint32_t, uint32_t> GetMinMaxBitratesBps(const VideoCodec& codec,
|
std::pair<uint32_t, uint32_t> GetMinMaxBitratesBps(const VideoCodec& codec,
|
||||||
size_t spatial_idx) {
|
size_t spatial_idx) {
|
||||||
uint32_t min_bitrate = codec.minBitrate;
|
uint32_t min_bitrate = codec.minBitrate;
|
||||||
@ -134,9 +137,14 @@ class QualityTestVideoEncoder : public VideoEncoder,
|
|||||||
int32_t InitEncode(const VideoCodec* codec_settings,
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override {
|
size_t max_payload_size) override {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||||
|
const Settings& settings) override {
|
||||||
codec_settings_ = *codec_settings;
|
codec_settings_ = *codec_settings;
|
||||||
return encoder_->InitEncode(codec_settings, number_of_cores,
|
return encoder_->InitEncode(codec_settings, settings);
|
||||||
max_payload_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t RegisterEncodeCompleteCallback(
|
int32_t RegisterEncodeCompleteCallback(
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
#include "api/test/simulated_network.h"
|
#include "api/test/simulated_network.h"
|
||||||
#include "api/video/encoded_image.h"
|
#include "api/video/encoded_image.h"
|
||||||
#include "api/video/video_bitrate_allocation.h"
|
#include "api/video/video_bitrate_allocation.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "call/call.h"
|
#include "call/call.h"
|
||||||
#include "call/fake_network_pipe.h"
|
#include "call/fake_network_pipe.h"
|
||||||
#include "call/rtp_transport_controller_send.h"
|
#include "call/rtp_transport_controller_send.h"
|
||||||
@ -1978,12 +1979,18 @@ TEST_F(VideoSendStreamTest,
|
|||||||
int32_t InitEncode(const VideoCodec* config,
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override {
|
size_t max_payload_size) override {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
|
const Settings& settings) override {
|
||||||
rtc::CritScope lock(&crit_);
|
rtc::CritScope lock(&crit_);
|
||||||
last_initialized_frame_width_ = config->width;
|
last_initialized_frame_width_ = config->width;
|
||||||
last_initialized_frame_height_ = config->height;
|
last_initialized_frame_height_ = config->height;
|
||||||
++number_of_initializations_;
|
++number_of_initializations_;
|
||||||
init_encode_called_.Set();
|
init_encode_called_.Set();
|
||||||
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
|
return FakeEncoder::InitEncode(config, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t Encode(const VideoFrame& input_image,
|
int32_t Encode(const VideoFrame& input_image,
|
||||||
@ -2038,10 +2045,16 @@ TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
|
|||||||
int32_t InitEncode(const VideoCodec* config,
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override {
|
size_t max_payload_size) override {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
|
const Settings& settings) override {
|
||||||
rtc::CritScope lock(&crit_);
|
rtc::CritScope lock(&crit_);
|
||||||
start_bitrate_kbps_ = config->startBitrate;
|
start_bitrate_kbps_ = config->startBitrate;
|
||||||
start_bitrate_changed_.Set();
|
start_bitrate_changed_.Set();
|
||||||
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
|
return FakeEncoder::InitEncode(config, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetRates(const RateControlParameters& parameters) override {
|
void SetRates(const RateControlParameters& parameters) override {
|
||||||
@ -2112,9 +2125,15 @@ class StartStopBitrateObserver : public test::FakeEncoder {
|
|||||||
int32_t InitEncode(const VideoCodec* config,
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override {
|
size_t max_payload_size) override {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
|
const Settings& settings) override {
|
||||||
rtc::CritScope lock(&crit_);
|
rtc::CritScope lock(&crit_);
|
||||||
encoder_init_.Set();
|
encoder_init_.Set();
|
||||||
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
|
return FakeEncoder::InitEncode(config, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetRates(const RateControlParameters& parameters) override {
|
void SetRates(const RateControlParameters& parameters) override {
|
||||||
@ -2311,6 +2330,12 @@ TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
|
|||||||
int32_t InitEncode(const VideoCodec* codecSettings,
|
int32_t InitEncode(const VideoCodec* codecSettings,
|
||||||
int32_t numberOfCores,
|
int32_t numberOfCores,
|
||||||
size_t maxPayloadSize) override {
|
size_t maxPayloadSize) override {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec* codecSettings,
|
||||||
|
const Settings& settings) override {
|
||||||
rtc::CritScope lock(&crit_);
|
rtc::CritScope lock(&crit_);
|
||||||
EXPECT_FALSE(initialized_);
|
EXPECT_FALSE(initialized_);
|
||||||
initialized_ = true;
|
initialized_ = true;
|
||||||
@ -2428,6 +2453,12 @@ TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
|
|||||||
int32_t InitEncode(const VideoCodec* config,
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override {
|
size_t max_payload_size) override {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
|
const Settings& settings) override {
|
||||||
if (num_initializations_ == 0) {
|
if (num_initializations_ == 0) {
|
||||||
// Verify default values.
|
// Verify default values.
|
||||||
EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
|
EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
|
||||||
@ -2437,7 +2468,7 @@ TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
|
|||||||
}
|
}
|
||||||
++num_initializations_;
|
++num_initializations_;
|
||||||
init_encode_event_.Set();
|
init_encode_event_.Set();
|
||||||
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
|
return FakeEncoder::InitEncode(config, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerformTest() override {
|
void PerformTest() override {
|
||||||
@ -2507,11 +2538,17 @@ class VideoCodecConfigObserver : public test::SendTest,
|
|||||||
int32_t InitEncode(const VideoCodec* config,
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override {
|
size_t max_payload_size) override {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
|
const Settings& settings) override {
|
||||||
EXPECT_EQ(video_codec_type_, config->codecType);
|
EXPECT_EQ(video_codec_type_, config->codecType);
|
||||||
VerifyCodecSpecifics(*config);
|
VerifyCodecSpecifics(*config);
|
||||||
++num_initializations_;
|
++num_initializations_;
|
||||||
init_encode_event_.Set();
|
init_encode_event_.Set();
|
||||||
return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
|
return FakeEncoder::InitEncode(config, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitCodecSpecifics();
|
void InitCodecSpecifics();
|
||||||
@ -2755,14 +2792,20 @@ TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
|
|||||||
int32_t InitEncode(const VideoCodec* config,
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override {
|
size_t max_payload_size) override {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
|
const Settings& settings) override {
|
||||||
EXPECT_EQ(config->numberOfSimulcastStreams, 1);
|
EXPECT_EQ(config->numberOfSimulcastStreams, 1);
|
||||||
EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
|
EXPECT_EQ(static_cast<unsigned int>(kScreencastMaxTargetBitrateDeltaKbps),
|
||||||
config->simulcastStream[0].maxBitrate -
|
config->simulcastStream[0].maxBitrate -
|
||||||
config->simulcastStream[0].targetBitrate);
|
config->simulcastStream[0].targetBitrate);
|
||||||
observation_complete_.Set();
|
observation_complete_.Set();
|
||||||
return test::FakeEncoder::InitEncode(config, number_of_cores,
|
return test::FakeEncoder::InitEncode(config, settings);
|
||||||
max_payload_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModifyVideoConfigs(
|
void ModifyVideoConfigs(
|
||||||
VideoSendStream::Config* send_config,
|
VideoSendStream::Config* send_config,
|
||||||
std::vector<VideoReceiveStream::Config>* receive_configs,
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
||||||
@ -2820,6 +2863,12 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
|
|||||||
int32_t InitEncode(const VideoCodec* codecSettings,
|
int32_t InitEncode(const VideoCodec* codecSettings,
|
||||||
int32_t numberOfCores,
|
int32_t numberOfCores,
|
||||||
size_t maxPayloadSize) override {
|
size_t maxPayloadSize) override {
|
||||||
|
RTC_NOTREACHED();
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec* codecSettings,
|
||||||
|
const Settings& settings) override {
|
||||||
EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
|
EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
|
||||||
EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
|
EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
|
||||||
if (num_initializations_ == 0) {
|
if (num_initializations_ == 0) {
|
||||||
@ -2847,8 +2896,7 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
|
|||||||
++num_initializations_;
|
++num_initializations_;
|
||||||
init_encode_event_.Set();
|
init_encode_event_.Set();
|
||||||
|
|
||||||
return FakeEncoder::InitEncode(codecSettings, numberOfCores,
|
return FakeEncoder::InitEncode(codecSettings, settings);
|
||||||
maxPayloadSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetRates(const RateControlParameters& parameters) override {
|
void SetRates(const RateControlParameters& parameters) override {
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
#include "api/video/encoded_image.h"
|
#include "api/video/encoded_image.h"
|
||||||
#include "api/video/i420_buffer.h"
|
#include "api/video/i420_buffer.h"
|
||||||
#include "api/video/video_bitrate_allocator_factory.h"
|
#include "api/video/video_bitrate_allocator_factory.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "modules/video_coding/codecs/vp9/svc_rate_allocator.h"
|
#include "modules/video_coding/codecs/vp9/svc_rate_allocator.h"
|
||||||
#include "modules/video_coding/include/video_codec_initializer.h"
|
#include "modules/video_coding/include/video_codec_initializer.h"
|
||||||
#include "modules/video_coding/include/video_coding.h"
|
#include "modules/video_coding/include/video_coding.h"
|
||||||
@ -732,10 +733,13 @@ void VideoStreamEncoder::ReconfigureEncoder() {
|
|||||||
encoder_config_.video_format);
|
encoder_config_.video_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (encoder_->InitEncode(&send_codec_, number_of_cores_,
|
const size_t max_data_payload_length = max_data_payload_length_ > 0
|
||||||
max_data_payload_length_ > 0
|
? max_data_payload_length_
|
||||||
? max_data_payload_length_
|
: kDefaultPayloadSize;
|
||||||
: kDefaultPayloadSize) != 0) {
|
if (encoder_->InitEncode(
|
||||||
|
&send_codec_,
|
||||||
|
VideoEncoder::Settings(settings_.capabilities, number_of_cores_,
|
||||||
|
max_data_payload_length)) != 0) {
|
||||||
RTC_LOG(LS_ERROR) << "Failed to initialize the encoder associated with "
|
RTC_LOG(LS_ERROR) << "Failed to initialize the encoder associated with "
|
||||||
"codec type: "
|
"codec type: "
|
||||||
<< CodecTypeToPayloadString(send_codec_.codecType)
|
<< CodecTypeToPayloadString(send_codec_.codecType)
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
#include "api/video/builtin_video_bitrate_allocator_factory.h"
|
#include "api/video/builtin_video_bitrate_allocator_factory.h"
|
||||||
#include "api/video/i420_buffer.h"
|
#include "api/video/i420_buffer.h"
|
||||||
#include "api/video/video_bitrate_allocation.h"
|
#include "api/video/video_bitrate_allocation.h"
|
||||||
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||||
#include "api/video_codecs/vp8_temporal_layers_factory.h"
|
#include "api/video_codecs/vp8_temporal_layers_factory.h"
|
||||||
#include "common_video/h264/h264_common.h"
|
#include "common_video/h264/h264_common.h"
|
||||||
@ -719,8 +720,13 @@ class VideoStreamEncoderTest : public ::testing::Test {
|
|||||||
int32_t InitEncode(const VideoCodec* config,
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
int32_t number_of_cores,
|
int32_t number_of_cores,
|
||||||
size_t max_payload_size) override {
|
size_t max_payload_size) override {
|
||||||
int res =
|
RTC_NOTREACHED();
|
||||||
FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec* config,
|
||||||
|
const Settings& settings) override {
|
||||||
|
int res = FakeEncoder::InitEncode(config, settings);
|
||||||
rtc::CritScope lock(&local_crit_sect_);
|
rtc::CritScope lock(&local_crit_sect_);
|
||||||
EXPECT_EQ(initialized_, EncoderState::kUninitialized);
|
EXPECT_EQ(initialized_, EncoderState::kUninitialized);
|
||||||
if (config->codecType == kVideoCodecVP8) {
|
if (config->codecType == kVideoCodecVP8) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user