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:
Magnus Jedvert
2017-11-17 14:44:55 +01:00
committed by Commit Bot
parent f90b457387
commit df4883dbf0
14 changed files with 301 additions and 203 deletions

View File

@ -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(

View File

@ -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

View File

@ -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_

View File

@ -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);

View File

@ -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_;

View File

@ -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:

View File

@ -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() {}

View File

@ -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_;
};

View File

@ -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,

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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();
}

View File

@ -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_;