Reland "Update internal encoder factory to new interface"
This is a reland of 2c8c8e26fc58a0f2789b7a5cd2646a8319c14d3e Original change's description: > Update internal encoder factory to new interface > > TBR=stefan@webrtc.org > > Bug: webrtc:7925 > Change-Id: I0bb97acdf0d58a9ce531ecdd672bb17ef96360df > Reviewed-on: https://webrtc-review.googlesource.com/21162 > Commit-Queue: Magnus Jedvert <magjed@webrtc.org> > Reviewed-by: Anders Carlsson <andersc@webrtc.org> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#20717} TBR=andersc@webrtc.org,brandt@webrtc.org,stefan@webrtc.org Bug: webrtc:7925 Change-Id: I0d269b3edb029e372a36c3b461a577bca2b6d0cb Reviewed-on: https://webrtc-review.googlesource.com/24000 Reviewed-by: Magnus Jedvert <magjed@webrtc.org> Commit-Queue: Magnus Jedvert <magjed@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20747}
This commit is contained in:
committed by
Commit Bot
parent
f90b457387
commit
df4883dbf0
@ -61,32 +61,70 @@ bool IsFormatSupported(
|
||||
return false;
|
||||
}
|
||||
|
||||
class EncoderAdapter : public webrtc::VideoEncoderFactory {
|
||||
// Converts the cricket::WebRtcVideoEncoderFactory to a
|
||||
// webrtc::VideoEncoderFactory (without adding any simulcast or SW fallback).
|
||||
class CricketToWebRtcEncoderFactory : public webrtc::VideoEncoderFactory {
|
||||
public:
|
||||
explicit EncoderAdapter(
|
||||
explicit CricketToWebRtcEncoderFactory(
|
||||
std::unique_ptr<WebRtcVideoEncoderFactory> external_encoder_factory)
|
||||
: internal_encoder_factory_(new InternalEncoderFactory()),
|
||||
external_encoder_factory_(std::move(external_encoder_factory)) {}
|
||||
: external_encoder_factory_(std::move(external_encoder_factory)) {}
|
||||
|
||||
webrtc::VideoEncoderFactory::CodecInfo QueryVideoEncoder(
|
||||
const webrtc::SdpVideoFormat& format) const {
|
||||
const VideoCodec codec(format);
|
||||
if (external_encoder_factory_ != nullptr &&
|
||||
FindMatchingCodec(external_encoder_factory_->supported_codecs(),
|
||||
codec)) {
|
||||
// Format is supported by the external factory.
|
||||
const webrtc::VideoCodecType codec_type =
|
||||
webrtc::PayloadStringToCodecType(codec.name);
|
||||
webrtc::VideoEncoderFactory::CodecInfo info;
|
||||
const webrtc::SdpVideoFormat& format) const override {
|
||||
CodecInfo info;
|
||||
if (!external_encoder_factory_)
|
||||
return info;
|
||||
|
||||
info.has_internal_source =
|
||||
external_encoder_factory_->EncoderTypeHasInternalSource(codec_type);
|
||||
external_encoder_factory_->EncoderTypeHasInternalSource(
|
||||
webrtc::PayloadStringToCodecType(format.name));
|
||||
info.is_hardware_accelerated = true;
|
||||
return info;
|
||||
}
|
||||
|
||||
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override {
|
||||
if (!external_encoder_factory_)
|
||||
return std::vector<webrtc::SdpVideoFormat>();
|
||||
|
||||
std::vector<webrtc::SdpVideoFormat> formats;
|
||||
for (const VideoCodec& codec :
|
||||
external_encoder_factory_->supported_codecs()) {
|
||||
formats.push_back(webrtc::SdpVideoFormat(codec.name, codec.params));
|
||||
}
|
||||
return formats;
|
||||
}
|
||||
|
||||
std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(
|
||||
const webrtc::SdpVideoFormat& format) override {
|
||||
return CreateScopedVideoEncoder(external_encoder_factory_.get(),
|
||||
VideoCodec(format));
|
||||
}
|
||||
|
||||
private:
|
||||
const std::unique_ptr<WebRtcVideoEncoderFactory> external_encoder_factory_;
|
||||
};
|
||||
|
||||
// This class combines an external factory with the internal factory and adds
|
||||
// internal SW codecs, simulcast, and SW fallback wrappers.
|
||||
class EncoderAdapter : public webrtc::VideoEncoderFactory {
|
||||
public:
|
||||
explicit EncoderAdapter(
|
||||
std::unique_ptr<WebRtcVideoEncoderFactory> external_encoder_factory)
|
||||
: internal_encoder_factory_(new webrtc::InternalEncoderFactory()),
|
||||
external_encoder_factory_(
|
||||
rtc::MakeUnique<CricketToWebRtcEncoderFactory>(
|
||||
std::move(external_encoder_factory))) {}
|
||||
|
||||
webrtc::VideoEncoderFactory::CodecInfo QueryVideoEncoder(
|
||||
const webrtc::SdpVideoFormat& format) const override {
|
||||
if (IsFormatSupported(external_encoder_factory_->GetSupportedFormats(),
|
||||
format)) {
|
||||
return external_encoder_factory_->QueryVideoEncoder(format);
|
||||
}
|
||||
|
||||
// Format must be one of the internal formats.
|
||||
RTC_DCHECK(FindMatchingCodec(internal_encoder_factory_->supported_codecs(),
|
||||
codec));
|
||||
RTC_DCHECK(IsFormatSupported(
|
||||
internal_encoder_factory_->GetSupportedFormats(), format));
|
||||
webrtc::VideoEncoderFactory::CodecInfo info;
|
||||
info.has_internal_source = false;
|
||||
info.is_hardware_accelerated = false;
|
||||
@ -94,31 +132,27 @@ class EncoderAdapter : public webrtc::VideoEncoderFactory {
|
||||
}
|
||||
|
||||
std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(
|
||||
const webrtc::SdpVideoFormat& format) {
|
||||
const VideoCodec codec(format);
|
||||
|
||||
const webrtc::SdpVideoFormat& format) override {
|
||||
// Try creating internal encoder.
|
||||
std::unique_ptr<webrtc::VideoEncoder> internal_encoder;
|
||||
if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(),
|
||||
codec)) {
|
||||
if (IsFormatSupported(internal_encoder_factory_->GetSupportedFormats(),
|
||||
format)) {
|
||||
internal_encoder =
|
||||
CodecNamesEq(format.name.c_str(), kVp8CodecName)
|
||||
? rtc::MakeUnique<webrtc::VP8EncoderSimulcastProxy>(
|
||||
internal_encoder_factory_.get())
|
||||
: std::unique_ptr<webrtc::VideoEncoder>(
|
||||
internal_encoder_factory_->CreateVideoEncoder(codec));
|
||||
: internal_encoder_factory_->CreateVideoEncoder(format);
|
||||
}
|
||||
|
||||
// Try creating external encoder.
|
||||
std::unique_ptr<webrtc::VideoEncoder> external_encoder;
|
||||
if (external_encoder_factory_ != nullptr &&
|
||||
FindMatchingCodec(external_encoder_factory_->supported_codecs(),
|
||||
codec)) {
|
||||
external_encoder = CodecNamesEq(format.name.c_str(), kVp8CodecName)
|
||||
if (IsFormatSupported(external_encoder_factory_->GetSupportedFormats(),
|
||||
format)) {
|
||||
external_encoder =
|
||||
CodecNamesEq(format.name.c_str(), kVp8CodecName)
|
||||
? rtc::MakeUnique<webrtc::SimulcastEncoderAdapter>(
|
||||
external_encoder_factory_.get())
|
||||
: CreateScopedVideoEncoder(
|
||||
external_encoder_factory_.get(), codec);
|
||||
: external_encoder_factory_->CreateVideoEncoder(format);
|
||||
}
|
||||
|
||||
if (internal_encoder && external_encoder) {
|
||||
@ -131,34 +165,28 @@ class EncoderAdapter : public webrtc::VideoEncoderFactory {
|
||||
: std::move(internal_encoder);
|
||||
}
|
||||
|
||||
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const {
|
||||
std::vector<VideoCodec> codecs =
|
||||
InternalEncoderFactory().supported_codecs();
|
||||
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override {
|
||||
std::vector<webrtc::SdpVideoFormat> formats =
|
||||
internal_encoder_factory_->GetSupportedFormats();
|
||||
|
||||
// Add external codecs.
|
||||
if (external_encoder_factory_ != nullptr) {
|
||||
const std::vector<VideoCodec>& external_codecs =
|
||||
external_encoder_factory_->supported_codecs();
|
||||
for (const VideoCodec& codec : external_codecs) {
|
||||
for (const webrtc::SdpVideoFormat& format :
|
||||
external_encoder_factory_->GetSupportedFormats()) {
|
||||
// Don't add same codec twice.
|
||||
if (!FindMatchingCodec(codecs, codec))
|
||||
codecs.push_back(codec);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<webrtc::SdpVideoFormat> formats;
|
||||
for (const VideoCodec& codec : codecs) {
|
||||
formats.push_back(webrtc::SdpVideoFormat(codec.name, codec.params));
|
||||
if (!IsFormatSupported(formats, format))
|
||||
formats.push_back(format);
|
||||
}
|
||||
|
||||
return formats;
|
||||
}
|
||||
|
||||
private:
|
||||
const std::unique_ptr<WebRtcVideoEncoderFactory> internal_encoder_factory_;
|
||||
const std::unique_ptr<WebRtcVideoEncoderFactory> external_encoder_factory_;
|
||||
const std::unique_ptr<webrtc::VideoEncoderFactory> internal_encoder_factory_;
|
||||
const std::unique_ptr<webrtc::VideoEncoderFactory> external_encoder_factory_;
|
||||
};
|
||||
|
||||
// This class combines an external factory with the internal factory and adds
|
||||
// internal SW codecs, simulcast, and SW fallback wrappers.
|
||||
class DecoderAdapter : public webrtc::VideoDecoderFactory {
|
||||
public:
|
||||
explicit DecoderAdapter(
|
||||
|
||||
@ -15,9 +15,10 @@
|
||||
#include "modules/video_coding/codecs/h264/include/h264.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
||||
#include "modules/video_coding/codecs/vp9/include/vp9.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "system_wrappers/include/field_trial.h"
|
||||
|
||||
namespace cricket {
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
@ -33,55 +34,55 @@ bool IsFlexfecAdvertisedFieldTrialEnabled() {
|
||||
|
||||
} // namespace
|
||||
|
||||
InternalEncoderFactory::InternalEncoderFactory() {
|
||||
supported_codecs_.push_back(VideoCodec(kVp8CodecName));
|
||||
std::vector<SdpVideoFormat> InternalEncoderFactory::GetSupportedFormats()
|
||||
const {
|
||||
std::vector<SdpVideoFormat> supported_codecs;
|
||||
supported_codecs.push_back(SdpVideoFormat(cricket::kVp8CodecName));
|
||||
if (webrtc::VP9Encoder::IsSupported())
|
||||
supported_codecs_.push_back(VideoCodec(kVp9CodecName));
|
||||
supported_codecs.push_back(SdpVideoFormat(cricket::kVp9CodecName));
|
||||
|
||||
for (const webrtc::SdpVideoFormat& format : webrtc::SupportedH264Codecs())
|
||||
supported_codecs_.push_back(VideoCodec(format));
|
||||
supported_codecs.push_back(format);
|
||||
|
||||
supported_codecs_.push_back(VideoCodec(kRedCodecName));
|
||||
supported_codecs_.push_back(VideoCodec(kUlpfecCodecName));
|
||||
supported_codecs.push_back(SdpVideoFormat(cricket::kRedCodecName));
|
||||
supported_codecs.push_back(SdpVideoFormat(cricket::kUlpfecCodecName));
|
||||
|
||||
if (IsFlexfecAdvertisedFieldTrialEnabled()) {
|
||||
VideoCodec flexfec_codec(kFlexfecCodecName);
|
||||
// This value is currently arbitrarily set to 10 seconds. (The unit
|
||||
// is microseconds.) This parameter MUST be present in the SDP, but
|
||||
// we never use the actual value anywhere in our code however.
|
||||
// TODO(brandtr): Consider honouring this value in the sender and receiver.
|
||||
flexfec_codec.SetParam(kFlexfecFmtpRepairWindow, "10000000");
|
||||
supported_codecs_.push_back(flexfec_codec);
|
||||
SdpVideoFormat::Parameters params = {
|
||||
{cricket::kFlexfecFmtpRepairWindow, "10000000"}};
|
||||
supported_codecs.push_back(
|
||||
SdpVideoFormat(cricket::kFlexfecCodecName, params));
|
||||
}
|
||||
|
||||
return supported_codecs;
|
||||
}
|
||||
|
||||
InternalEncoderFactory::~InternalEncoderFactory() {}
|
||||
VideoEncoderFactory::CodecInfo InternalEncoderFactory::QueryVideoEncoder(
|
||||
const SdpVideoFormat& format) const {
|
||||
CodecInfo info;
|
||||
info.is_hardware_accelerated = false;
|
||||
info.has_internal_source = false;
|
||||
return info;
|
||||
}
|
||||
|
||||
// WebRtcVideoEncoderFactory implementation.
|
||||
webrtc::VideoEncoder* InternalEncoderFactory::CreateVideoEncoder(
|
||||
const VideoCodec& codec) {
|
||||
const webrtc::VideoCodecType codec_type =
|
||||
webrtc::PayloadStringToCodecType(codec.name);
|
||||
switch (codec_type) {
|
||||
case webrtc::kVideoCodecH264:
|
||||
return webrtc::H264Encoder::Create(codec).release();
|
||||
case webrtc::kVideoCodecVP8:
|
||||
return webrtc::VP8Encoder::Create().release();
|
||||
case webrtc::kVideoCodecVP9:
|
||||
return webrtc::VP9Encoder::Create().release();
|
||||
default:
|
||||
std::unique_ptr<VideoEncoder> InternalEncoderFactory::CreateVideoEncoder(
|
||||
const SdpVideoFormat& format) {
|
||||
if (cricket::CodecNamesEq(format.name, cricket::kVp8CodecName))
|
||||
return VP8Encoder::Create();
|
||||
|
||||
if (cricket::CodecNamesEq(format.name, cricket::kVp9CodecName))
|
||||
return VP9Encoder::Create();
|
||||
|
||||
if (cricket::CodecNamesEq(format.name, cricket::kH264CodecName))
|
||||
return H264Encoder::Create(cricket::VideoCodec(format));
|
||||
|
||||
RTC_LOG(LS_ERROR) << "Trying to created encoder of unsupported format "
|
||||
<< format.name;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<VideoCodec>&
|
||||
InternalEncoderFactory::supported_codecs() const {
|
||||
return supported_codecs_;
|
||||
}
|
||||
|
||||
void InternalEncoderFactory::DestroyVideoEncoder(
|
||||
webrtc::VideoEncoder* encoder) {
|
||||
delete encoder;
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
} // namespace webrtc
|
||||
|
||||
@ -11,27 +11,23 @@
|
||||
#ifndef MEDIA_ENGINE_INTERNALENCODERFACTORY_H_
|
||||
#define MEDIA_ENGINE_INTERNALENCODERFACTORY_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "media/engine/webrtcvideoencoderfactory.h"
|
||||
#include "api/video_codecs/video_encoder_factory.h"
|
||||
|
||||
namespace cricket {
|
||||
namespace webrtc {
|
||||
|
||||
class InternalEncoderFactory : public WebRtcVideoEncoderFactory {
|
||||
class InternalEncoderFactory : public VideoEncoderFactory {
|
||||
public:
|
||||
InternalEncoderFactory();
|
||||
virtual ~InternalEncoderFactory();
|
||||
std::vector<SdpVideoFormat> GetSupportedFormats() const override;
|
||||
|
||||
// WebRtcVideoEncoderFactory implementation.
|
||||
webrtc::VideoEncoder* CreateVideoEncoder(
|
||||
const cricket::VideoCodec& codec) override;
|
||||
const std::vector<cricket::VideoCodec>& supported_codecs() const override;
|
||||
void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override;
|
||||
CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
|
||||
|
||||
private:
|
||||
std::vector<cricket::VideoCodec> supported_codecs_;
|
||||
std::unique_ptr<VideoEncoder> CreateVideoEncoder(
|
||||
const SdpVideoFormat& format) override;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MEDIA_ENGINE_INTERNALENCODERFACTORY_H_
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include "libyuv/scale.h" // NOLINT
|
||||
|
||||
#include "api/video/i420_buffer.h"
|
||||
#include "api/video_codecs/video_encoder_factory.h"
|
||||
#include "media/engine/scopedvideoencoder.h"
|
||||
#include "modules/video_coding/codecs/vp8/screenshare_layers.h"
|
||||
#include "modules/video_coding/codecs/vp8/simulcast_rate_allocator.h"
|
||||
@ -134,10 +135,24 @@ class TemporalLayersFactoryAdapter : public webrtc::TemporalLayersFactory {
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
SimulcastEncoderAdapter::SimulcastEncoderAdapter(VideoEncoderFactory* factory)
|
||||
: inited_(0),
|
||||
factory_(factory),
|
||||
cricket_factory_(nullptr),
|
||||
encoded_complete_callback_(nullptr),
|
||||
implementation_name_("SimulcastEncoderAdapter") {
|
||||
// The adapter is typically created on the worker thread, but operated on
|
||||
// the encoder task queue.
|
||||
encoder_queue_.Detach();
|
||||
|
||||
memset(&codec_, 0, sizeof(webrtc::VideoCodec));
|
||||
}
|
||||
|
||||
SimulcastEncoderAdapter::SimulcastEncoderAdapter(
|
||||
cricket::WebRtcVideoEncoderFactory* factory)
|
||||
: inited_(0),
|
||||
factory_(factory),
|
||||
factory_(nullptr),
|
||||
cricket_factory_(factory),
|
||||
encoded_complete_callback_(nullptr),
|
||||
implementation_name_("SimulcastEncoderAdapter") {
|
||||
// The adapter is typically created on the worker thread, but operated on
|
||||
@ -246,7 +261,9 @@ int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst,
|
||||
encoder = std::move(stored_encoders_.top());
|
||||
stored_encoders_.pop();
|
||||
} else {
|
||||
encoder = CreateScopedVideoEncoder(factory_, cricket::VideoCodec("VP8"));
|
||||
encoder = factory_ ? factory_->CreateVideoEncoder(SdpVideoFormat("VP8"))
|
||||
: CreateScopedVideoEncoder(cricket_factory_,
|
||||
cricket::VideoCodec("VP8"));
|
||||
}
|
||||
|
||||
ret = encoder->InitEncode(&stream_codec, number_of_cores, max_payload_size);
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
namespace webrtc {
|
||||
|
||||
class SimulcastRateAllocator;
|
||||
class VideoEncoderFactory;
|
||||
|
||||
// SimulcastEncoderAdapter implements simulcast support by creating multiple
|
||||
// webrtc::VideoEncoder instances with the given VideoEncoderFactory.
|
||||
@ -33,6 +34,8 @@ class SimulcastRateAllocator;
|
||||
// interfaces should be called from the encoder task queue.
|
||||
class SimulcastEncoderAdapter : public VP8Encoder {
|
||||
public:
|
||||
explicit SimulcastEncoderAdapter(VideoEncoderFactory* factory);
|
||||
// Deprecated - use webrtc::VideoEncoderFactory instead.
|
||||
explicit SimulcastEncoderAdapter(cricket::WebRtcVideoEncoderFactory* factory);
|
||||
virtual ~SimulcastEncoderAdapter();
|
||||
|
||||
@ -96,7 +99,8 @@ class SimulcastEncoderAdapter : public VP8Encoder {
|
||||
void DestroyStoredEncoders();
|
||||
|
||||
volatile int inited_; // Accessed atomically.
|
||||
cricket::WebRtcVideoEncoderFactory* const factory_;
|
||||
VideoEncoderFactory* const factory_;
|
||||
cricket::WebRtcVideoEncoderFactory* const cricket_factory_;
|
||||
VideoCodec codec_;
|
||||
std::vector<StreamInfo> streaminfos_;
|
||||
EncodedImageCallback* encoded_complete_callback_;
|
||||
|
||||
@ -12,6 +12,8 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "api/video_codecs/sdp_video_format.h"
|
||||
#include "api/video_codecs/video_encoder_factory.h"
|
||||
#include "common_video/include/video_frame_buffer.h"
|
||||
#include "media/engine/internalencoderfactory.h"
|
||||
#include "media/engine/simulcast_encoder_adapter.h"
|
||||
@ -25,8 +27,7 @@ namespace testing {
|
||||
|
||||
class TestSimulcastEncoderAdapter : public TestVp8Simulcast {
|
||||
public:
|
||||
TestSimulcastEncoderAdapter()
|
||||
: factory_(new cricket::InternalEncoderFactory()) {}
|
||||
TestSimulcastEncoderAdapter() : factory_(new InternalEncoderFactory()) {}
|
||||
|
||||
protected:
|
||||
std::unique_ptr<VP8Encoder> CreateEncoder() override {
|
||||
@ -37,7 +38,7 @@ class TestSimulcastEncoderAdapter : public TestVp8Simulcast {
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<cricket::WebRtcVideoEncoderFactory> factory_;
|
||||
std::unique_ptr<VideoEncoderFactory> factory_;
|
||||
};
|
||||
|
||||
TEST_F(TestSimulcastEncoderAdapter, TestKeyFrameRequestsOnAllStreams) {
|
||||
@ -92,8 +93,34 @@ TEST_F(TestSimulcastEncoderAdapter, TestSpatioTemporalLayers321PatternEncoder) {
|
||||
TestVp8Simulcast::TestSpatioTemporalLayers321PatternEncoder();
|
||||
}
|
||||
|
||||
class MockVideoEncoder;
|
||||
|
||||
class MockVideoEncoderFactory : public VideoEncoderFactory {
|
||||
public:
|
||||
std::vector<SdpVideoFormat> GetSupportedFormats() const override;
|
||||
|
||||
std::unique_ptr<VideoEncoder> CreateVideoEncoder(
|
||||
const SdpVideoFormat& format) override;
|
||||
|
||||
CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
|
||||
|
||||
const std::vector<MockVideoEncoder*>& encoders() const;
|
||||
void SetEncoderNames(const std::vector<const char*>& encoder_names);
|
||||
void set_init_encode_return_value(int32_t value);
|
||||
|
||||
void DestroyVideoEncoder(VideoEncoder* encoder);
|
||||
|
||||
private:
|
||||
int32_t init_encode_return_value_ = 0;
|
||||
std::vector<MockVideoEncoder*> encoders_;
|
||||
std::vector<const char*> encoder_names_;
|
||||
};
|
||||
|
||||
class MockVideoEncoder : public VideoEncoder {
|
||||
public:
|
||||
explicit MockVideoEncoder(MockVideoEncoderFactory* factory)
|
||||
: factory_(factory) {}
|
||||
|
||||
// TODO(nisse): Valid overrides commented out, because the gmock
|
||||
// methods don't use any override declarations, and we want to avoid
|
||||
// warnings from -Winconsistent-missing-override. See
|
||||
@ -131,7 +158,7 @@ class MockVideoEncoder : public VideoEncoder {
|
||||
return supports_native_handle_;
|
||||
}
|
||||
|
||||
virtual ~MockVideoEncoder() {}
|
||||
virtual ~MockVideoEncoder() { factory_->DestroyVideoEncoder(this); }
|
||||
|
||||
const VideoCodec& codec() const { return codec_; }
|
||||
|
||||
@ -158,6 +185,7 @@ class MockVideoEncoder : public VideoEncoder {
|
||||
MOCK_CONST_METHOD0(ImplementationName, const char*());
|
||||
|
||||
private:
|
||||
MockVideoEncoderFactory* const factory_;
|
||||
bool supports_native_handle_ = false;
|
||||
int32_t init_encode_return_value_ = 0;
|
||||
BitrateAllocation last_set_bitrate_;
|
||||
@ -166,53 +194,50 @@ class MockVideoEncoder : public VideoEncoder {
|
||||
EncodedImageCallback* callback_;
|
||||
};
|
||||
|
||||
class MockVideoEncoderFactory : public cricket::WebRtcVideoEncoderFactory {
|
||||
public:
|
||||
MockVideoEncoderFactory() {
|
||||
supported_codecs_.push_back(cricket::VideoCodec("VP8"));
|
||||
}
|
||||
std::vector<SdpVideoFormat> MockVideoEncoderFactory::GetSupportedFormats()
|
||||
const {
|
||||
std::vector<SdpVideoFormat> formats = {SdpVideoFormat("VP8")};
|
||||
return formats;
|
||||
}
|
||||
|
||||
const std::vector<cricket::VideoCodec>& supported_codecs() const override {
|
||||
return supported_codecs_;
|
||||
}
|
||||
|
||||
VideoEncoder* CreateVideoEncoder(const cricket::VideoCodec& codec) override {
|
||||
MockVideoEncoder* encoder = new ::testing::NiceMock<MockVideoEncoder>();
|
||||
std::unique_ptr<VideoEncoder> MockVideoEncoderFactory::CreateVideoEncoder(
|
||||
const SdpVideoFormat& format) {
|
||||
std::unique_ptr<MockVideoEncoder> encoder(
|
||||
new ::testing::NiceMock<MockVideoEncoder>(this));
|
||||
encoder->set_init_encode_return_value(init_encode_return_value_);
|
||||
const char* encoder_name = encoder_names_.empty()
|
||||
? "codec_implementation_name"
|
||||
: encoder_names_[encoders_.size()];
|
||||
ON_CALL(*encoder, ImplementationName()).WillByDefault(Return(encoder_name));
|
||||
encoders_.push_back(encoder);
|
||||
encoders_.push_back(encoder.get());
|
||||
return encoder;
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyVideoEncoder(VideoEncoder* encoder) override {
|
||||
void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
|
||||
for (size_t i = 0; i < encoders_.size(); ++i) {
|
||||
if (encoders_[i] == encoder) {
|
||||
encoders_.erase(encoders_.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete encoder;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~MockVideoEncoderFactory() {}
|
||||
VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
|
||||
const SdpVideoFormat& format) const {
|
||||
return CodecInfo();
|
||||
}
|
||||
|
||||
const std::vector<MockVideoEncoder*>& encoders() const { return encoders_; }
|
||||
void SetEncoderNames(const std::vector<const char*>& encoder_names) {
|
||||
const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
|
||||
const {
|
||||
return encoders_;
|
||||
}
|
||||
void MockVideoEncoderFactory::SetEncoderNames(
|
||||
const std::vector<const char*>& encoder_names) {
|
||||
encoder_names_ = encoder_names;
|
||||
}
|
||||
void set_init_encode_return_value(int32_t value) {
|
||||
}
|
||||
void MockVideoEncoderFactory::set_init_encode_return_value(int32_t value) {
|
||||
init_encode_return_value_ = value;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<cricket::VideoCodec> supported_codecs_;
|
||||
int32_t init_encode_return_value_ = 0;
|
||||
std::vector<MockVideoEncoder*> encoders_;
|
||||
std::vector<const char*> encoder_names_;
|
||||
};
|
||||
}
|
||||
|
||||
class TestSimulcastEncoderAdapterFakeHelper {
|
||||
public:
|
||||
|
||||
@ -15,10 +15,9 @@
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
VP8EncoderSimulcastProxy::VP8EncoderSimulcastProxy(
|
||||
cricket::WebRtcVideoEncoderFactory* factory)
|
||||
VP8EncoderSimulcastProxy::VP8EncoderSimulcastProxy(VideoEncoderFactory* factory)
|
||||
: factory_(factory), callback_(nullptr) {
|
||||
encoder_ = CreateScopedVideoEncoder(factory_, cricket::VideoCodec("VP8"));
|
||||
encoder_ = factory_->CreateVideoEncoder(SdpVideoFormat("VP8"));
|
||||
}
|
||||
|
||||
VP8EncoderSimulcastProxy::~VP8EncoderSimulcastProxy() {}
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "media/engine/webrtcvideoencoderfactory.h"
|
||||
#include "api/video_codecs/video_encoder_factory.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -24,8 +24,7 @@ namespace webrtc {
|
||||
// doesn't support simulcast for provided settings.
|
||||
class VP8EncoderSimulcastProxy : public VP8Encoder {
|
||||
public:
|
||||
explicit VP8EncoderSimulcastProxy(
|
||||
cricket::WebRtcVideoEncoderFactory* factory);
|
||||
explicit VP8EncoderSimulcastProxy(VideoEncoderFactory* factory);
|
||||
virtual ~VP8EncoderSimulcastProxy();
|
||||
|
||||
// Implements VideoEncoder.
|
||||
@ -48,7 +47,7 @@ class VP8EncoderSimulcastProxy : public VP8Encoder {
|
||||
const char* ImplementationName() const override;
|
||||
|
||||
private:
|
||||
cricket::WebRtcVideoEncoderFactory* const factory_;
|
||||
VideoEncoderFactory* const factory_;
|
||||
std::unique_ptr<VideoEncoder> encoder_;
|
||||
EncodedImageCallback* callback_;
|
||||
};
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "api/test/mock_video_encoder_factory.h"
|
||||
#include "media/engine/webrtcvideoencoderfactory.h"
|
||||
#include "modules/video_coding/codecs/vp8/temporal_layers.h"
|
||||
#include "modules/video_coding/include/video_codec_interface.h"
|
||||
@ -56,20 +57,6 @@ class MockEncoder : public VideoEncoder {
|
||||
MOCK_CONST_METHOD0(ImplementationName, const char*());
|
||||
};
|
||||
|
||||
class MockWebRtcVideoEncoderFactory
|
||||
: public cricket::WebRtcVideoEncoderFactory {
|
||||
public:
|
||||
MockWebRtcVideoEncoderFactory() {}
|
||||
virtual ~MockWebRtcVideoEncoderFactory() {}
|
||||
|
||||
MOCK_METHOD1(CreateVideoEncoder,
|
||||
webrtc::VideoEncoder*(const cricket::VideoCodec& codec));
|
||||
|
||||
MOCK_CONST_METHOD0(supported_codecs, std::vector<cricket::VideoCodec>&());
|
||||
|
||||
MOCK_METHOD1(DestroyVideoEncoder, void(webrtc::VideoEncoder*));
|
||||
};
|
||||
|
||||
TEST(VP8EncoderSimulcastProxy, ChoosesCorrectImplementation) {
|
||||
const std::string kImplementationName = "Fake";
|
||||
const std::string kSimulcastAdaptedImplementationName =
|
||||
@ -86,56 +73,56 @@ TEST(VP8EncoderSimulcastProxy, ChoosesCorrectImplementation) {
|
||||
test::kTestWidth, test::kTestHeight, 2, 5000, 1000, 1000, 56};
|
||||
codec_settings.numberOfSimulcastStreams = 3;
|
||||
|
||||
NiceMock<MockEncoder> mock_encoder;
|
||||
NiceMock<MockWebRtcVideoEncoderFactory> simulcast_factory;
|
||||
NiceMock<MockEncoder>* mock_encoder = new NiceMock<MockEncoder>();
|
||||
NiceMock<MockVideoEncoderFactory> simulcast_factory;
|
||||
|
||||
EXPECT_CALL(mock_encoder, InitEncode(_, _, _))
|
||||
EXPECT_CALL(*mock_encoder, InitEncode(_, _, _))
|
||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
||||
EXPECT_CALL(mock_encoder, ImplementationName())
|
||||
EXPECT_CALL(*mock_encoder, ImplementationName())
|
||||
.WillRepeatedly(Return(kImplementationName.c_str()));
|
||||
|
||||
EXPECT_CALL(simulcast_factory, CreateVideoEncoder(_))
|
||||
EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_))
|
||||
.Times(1)
|
||||
.WillOnce(Return(&mock_encoder));
|
||||
.WillOnce(Return(mock_encoder));
|
||||
|
||||
VP8EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory);
|
||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||
simulcast_enabled_proxy.InitEncode(&codec_settings, 4, 1200));
|
||||
EXPECT_EQ(kImplementationName, simulcast_enabled_proxy.ImplementationName());
|
||||
|
||||
NiceMock<MockEncoder> mock_encoder1;
|
||||
NiceMock<MockEncoder> mock_encoder2;
|
||||
NiceMock<MockEncoder> mock_encoder3;
|
||||
NiceMock<MockEncoder> mock_encoder4;
|
||||
NiceMock<MockWebRtcVideoEncoderFactory> nonsimulcast_factory;
|
||||
NiceMock<MockEncoder>* mock_encoder1 = new NiceMock<MockEncoder>();
|
||||
NiceMock<MockEncoder>* mock_encoder2 = new NiceMock<MockEncoder>();
|
||||
NiceMock<MockEncoder>* mock_encoder3 = new NiceMock<MockEncoder>();
|
||||
NiceMock<MockEncoder>* mock_encoder4 = new NiceMock<MockEncoder>();
|
||||
NiceMock<MockVideoEncoderFactory> nonsimulcast_factory;
|
||||
|
||||
EXPECT_CALL(mock_encoder1, InitEncode(_, _, _))
|
||||
EXPECT_CALL(*mock_encoder1, InitEncode(_, _, _))
|
||||
.WillOnce(
|
||||
Return(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED));
|
||||
EXPECT_CALL(mock_encoder1, ImplementationName())
|
||||
EXPECT_CALL(*mock_encoder1, ImplementationName())
|
||||
.WillRepeatedly(Return(kImplementationName.c_str()));
|
||||
|
||||
EXPECT_CALL(mock_encoder2, InitEncode(_, _, _))
|
||||
EXPECT_CALL(*mock_encoder2, InitEncode(_, _, _))
|
||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
||||
EXPECT_CALL(mock_encoder2, ImplementationName())
|
||||
EXPECT_CALL(*mock_encoder2, ImplementationName())
|
||||
.WillRepeatedly(Return(kImplementationName.c_str()));
|
||||
|
||||
EXPECT_CALL(mock_encoder3, InitEncode(_, _, _))
|
||||
EXPECT_CALL(*mock_encoder3, InitEncode(_, _, _))
|
||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
||||
EXPECT_CALL(mock_encoder3, ImplementationName())
|
||||
EXPECT_CALL(*mock_encoder3, ImplementationName())
|
||||
.WillRepeatedly(Return(kImplementationName.c_str()));
|
||||
|
||||
EXPECT_CALL(mock_encoder4, InitEncode(_, _, _))
|
||||
EXPECT_CALL(*mock_encoder4, InitEncode(_, _, _))
|
||||
.WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
|
||||
EXPECT_CALL(mock_encoder4, ImplementationName())
|
||||
EXPECT_CALL(*mock_encoder4, ImplementationName())
|
||||
.WillRepeatedly(Return(kImplementationName.c_str()));
|
||||
|
||||
EXPECT_CALL(nonsimulcast_factory, CreateVideoEncoder(_))
|
||||
EXPECT_CALL(nonsimulcast_factory, CreateVideoEncoderProxy(_))
|
||||
.Times(4)
|
||||
.WillOnce(Return(&mock_encoder1))
|
||||
.WillOnce(Return(&mock_encoder2))
|
||||
.WillOnce(Return(&mock_encoder3))
|
||||
.WillOnce(Return(&mock_encoder4));
|
||||
.WillOnce(Return(mock_encoder1))
|
||||
.WillOnce(Return(mock_encoder2))
|
||||
.WillOnce(Return(mock_encoder3))
|
||||
.WillOnce(Return(mock_encoder4));
|
||||
|
||||
VP8EncoderSimulcastProxy simulcast_disabled_proxy(&nonsimulcast_factory);
|
||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||
|
||||
@ -80,6 +80,40 @@ bool RunEncodeInRealTime(const TestConfig& config) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// An internal encoder factory in the old WebRtcVideoEncoderFactory format.
|
||||
// TODO(magjed): Update these tests to use new webrtc::VideoEncoderFactory
|
||||
// instead.
|
||||
class LegacyInternalEncoderFactory : public cricket::WebRtcVideoEncoderFactory {
|
||||
public:
|
||||
LegacyInternalEncoderFactory() {
|
||||
for (const SdpVideoFormat& format :
|
||||
InternalEncoderFactory().GetSupportedFormats()) {
|
||||
supported_codecs_.push_back(cricket::VideoCodec(format));
|
||||
}
|
||||
}
|
||||
|
||||
// WebRtcVideoEncoderFactory implementation.
|
||||
VideoEncoder* CreateVideoEncoder(const cricket::VideoCodec& codec) override {
|
||||
return InternalEncoderFactory()
|
||||
.CreateVideoEncoder(SdpVideoFormat(codec.name, codec.params))
|
||||
.release();
|
||||
}
|
||||
|
||||
const std::vector<cricket::VideoCodec>& supported_codecs() const override {
|
||||
return supported_codecs_;
|
||||
}
|
||||
|
||||
bool EncoderTypeHasInternalSource(
|
||||
webrtc::VideoCodecType type) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
void DestroyVideoEncoder(VideoEncoder* encoder) override { delete encoder; }
|
||||
|
||||
private:
|
||||
std::vector<cricket::VideoCodec> supported_codecs_;
|
||||
};
|
||||
|
||||
// An internal decoder factory in the old WebRtcVideoDecoderFactory format.
|
||||
// TODO(magjed): Update these tests to use new webrtc::VideoDecoderFactory
|
||||
// instead.
|
||||
@ -313,7 +347,7 @@ void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() {
|
||||
RTC_NOTREACHED() << "Only support HW encoder on Android and iOS.";
|
||||
#endif
|
||||
} else {
|
||||
encoder_factory.reset(new cricket::InternalEncoderFactory());
|
||||
encoder_factory.reset(new LegacyInternalEncoderFactory());
|
||||
}
|
||||
|
||||
std::unique_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory;
|
||||
@ -382,8 +416,8 @@ void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() {
|
||||
|
||||
if (config_.sw_fallback_encoder) {
|
||||
encoder_ = rtc::MakeUnique<VideoEncoderSoftwareFallbackWrapper>(
|
||||
std::unique_ptr<VideoEncoder>(
|
||||
cricket::InternalEncoderFactory().CreateVideoEncoder(codec)),
|
||||
InternalEncoderFactory().CreateVideoEncoder(
|
||||
SdpVideoFormat(codec.name, codec.params)),
|
||||
std::move(encoder_));
|
||||
}
|
||||
if (config_.sw_fallback_decoder) {
|
||||
|
||||
@ -516,11 +516,21 @@ bool MediaCodecVideoEncoder::EncodeTask::Run() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsFormatSupported(
|
||||
const std::vector<webrtc::SdpVideoFormat>& supported_formats,
|
||||
const std::string& name) {
|
||||
for (const webrtc::SdpVideoFormat& supported_format : supported_formats) {
|
||||
if (cricket::CodecNamesEq(name, supported_format.name))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MediaCodecVideoEncoder::ProcessHWError(
|
||||
bool reset_if_fallback_unavailable) {
|
||||
ALOGE << "ProcessHWError";
|
||||
if (FindMatchingCodec(cricket::InternalEncoderFactory().supported_codecs(),
|
||||
codec_)) {
|
||||
if (IsFormatSupported(InternalEncoderFactory().GetSupportedFormats(),
|
||||
codec_.name)) {
|
||||
ALOGE << "Fallback to SW encoder.";
|
||||
sw_fallback_required_ = true;
|
||||
return false;
|
||||
|
||||
@ -346,7 +346,7 @@ TEST_P(PictureIdTest, PictureIdIncreasingAfterStreamCountChangeVp8) {
|
||||
|
||||
TEST_P(PictureIdTest,
|
||||
PictureIdContinuousAfterReconfigureSimulcastEncoderAdapter) {
|
||||
cricket::InternalEncoderFactory internal_encoder_factory;
|
||||
InternalEncoderFactory internal_encoder_factory;
|
||||
SimulcastEncoderAdapter simulcast_encoder_adapter(&internal_encoder_factory);
|
||||
SetupEncoder(&simulcast_encoder_adapter);
|
||||
TestPictureIdContinuousAfterReconfigure({1, 3, 3, 1, 1});
|
||||
@ -354,7 +354,7 @@ TEST_P(PictureIdTest,
|
||||
|
||||
TEST_P(PictureIdTest,
|
||||
PictureIdIncreasingAfterRecreateStreamSimulcastEncoderAdapter) {
|
||||
cricket::InternalEncoderFactory internal_encoder_factory;
|
||||
InternalEncoderFactory internal_encoder_factory;
|
||||
SimulcastEncoderAdapter simulcast_encoder_adapter(&internal_encoder_factory);
|
||||
SetupEncoder(&simulcast_encoder_adapter);
|
||||
TestPictureIdIncreaseAfterRecreateStreams({1, 3, 3, 1, 1});
|
||||
@ -368,7 +368,7 @@ TEST_P(PictureIdTest,
|
||||
// If forced fallback is enabled, the picture id is set in the PayloadRouter
|
||||
// and the sequence should be continuous.
|
||||
if (GetParam() == kVp8ForcedFallbackEncoderEnabled) {
|
||||
cricket::InternalEncoderFactory internal_encoder_factory;
|
||||
InternalEncoderFactory internal_encoder_factory;
|
||||
SimulcastEncoderAdapter simulcast_encoder_adapter(
|
||||
&internal_encoder_factory);
|
||||
// Make sure that that the picture id is not reset if the stream count goes
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
#include <algorithm>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -1393,7 +1392,7 @@ void VideoQualityTest::SetupVideo(Transport* send_transport,
|
||||
// encoders usually can't natively do simulcast with different frame rates
|
||||
// for the different layers.
|
||||
video_encoder_.reset(
|
||||
new SimulcastEncoderAdapter(new cricket::InternalEncoderFactory()));
|
||||
new SimulcastEncoderAdapter(new InternalEncoderFactory()));
|
||||
} else {
|
||||
video_encoder_ = VP8Encoder::Create();
|
||||
}
|
||||
|
||||
@ -145,7 +145,6 @@ class VideoQualityTest : public test::CallTest {
|
||||
std::vector<std::unique_ptr<test::VideoCapturer>> thumbnail_capturers_;
|
||||
std::unique_ptr<test::FrameGenerator> frame_generator_;
|
||||
std::unique_ptr<VideoEncoder> video_encoder_;
|
||||
std::unique_ptr<cricket::WebRtcVideoEncoderFactory> vp8_encoder_factory_;
|
||||
|
||||
std::vector<std::unique_ptr<VideoEncoder>> thumbnail_encoders_;
|
||||
std::vector<VideoSendStream::Config> thumbnail_send_configs_;
|
||||
|
||||
Reference in New Issue
Block a user