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; 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: public:
explicit EncoderAdapter( explicit CricketToWebRtcEncoderFactory(
std::unique_ptr<WebRtcVideoEncoderFactory> external_encoder_factory) 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( webrtc::VideoEncoderFactory::CodecInfo QueryVideoEncoder(
const webrtc::SdpVideoFormat& format) const { const webrtc::SdpVideoFormat& format) const override {
const VideoCodec codec(format); CodecInfo info;
if (external_encoder_factory_ != nullptr && if (!external_encoder_factory_)
FindMatchingCodec(external_encoder_factory_->supported_codecs(), return info;
codec)) {
// Format is supported by the external factory.
const webrtc::VideoCodecType codec_type =
webrtc::PayloadStringToCodecType(codec.name);
webrtc::VideoEncoderFactory::CodecInfo info;
info.has_internal_source = info.has_internal_source =
external_encoder_factory_->EncoderTypeHasInternalSource(codec_type); external_encoder_factory_->EncoderTypeHasInternalSource(
webrtc::PayloadStringToCodecType(format.name));
info.is_hardware_accelerated = true; info.is_hardware_accelerated = true;
return info; 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. // Format must be one of the internal formats.
RTC_DCHECK(FindMatchingCodec(internal_encoder_factory_->supported_codecs(), RTC_DCHECK(IsFormatSupported(
codec)); internal_encoder_factory_->GetSupportedFormats(), format));
webrtc::VideoEncoderFactory::CodecInfo info; webrtc::VideoEncoderFactory::CodecInfo info;
info.has_internal_source = false; info.has_internal_source = false;
info.is_hardware_accelerated = false; info.is_hardware_accelerated = false;
@ -94,31 +132,27 @@ class EncoderAdapter : public webrtc::VideoEncoderFactory {
} }
std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder( std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(
const webrtc::SdpVideoFormat& format) { const webrtc::SdpVideoFormat& format) override {
const VideoCodec codec(format);
// Try creating internal encoder. // Try creating internal encoder.
std::unique_ptr<webrtc::VideoEncoder> internal_encoder; std::unique_ptr<webrtc::VideoEncoder> internal_encoder;
if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(), if (IsFormatSupported(internal_encoder_factory_->GetSupportedFormats(),
codec)) { format)) {
internal_encoder = internal_encoder =
CodecNamesEq(format.name.c_str(), kVp8CodecName) CodecNamesEq(format.name.c_str(), kVp8CodecName)
? rtc::MakeUnique<webrtc::VP8EncoderSimulcastProxy>( ? rtc::MakeUnique<webrtc::VP8EncoderSimulcastProxy>(
internal_encoder_factory_.get()) internal_encoder_factory_.get())
: std::unique_ptr<webrtc::VideoEncoder>( : internal_encoder_factory_->CreateVideoEncoder(format);
internal_encoder_factory_->CreateVideoEncoder(codec));
} }
// Try creating external encoder. // Try creating external encoder.
std::unique_ptr<webrtc::VideoEncoder> external_encoder; std::unique_ptr<webrtc::VideoEncoder> external_encoder;
if (external_encoder_factory_ != nullptr && if (IsFormatSupported(external_encoder_factory_->GetSupportedFormats(),
FindMatchingCodec(external_encoder_factory_->supported_codecs(), format)) {
codec)) { external_encoder =
external_encoder = CodecNamesEq(format.name.c_str(), kVp8CodecName) CodecNamesEq(format.name.c_str(), kVp8CodecName)
? rtc::MakeUnique<webrtc::SimulcastEncoderAdapter>( ? rtc::MakeUnique<webrtc::SimulcastEncoderAdapter>(
external_encoder_factory_.get()) external_encoder_factory_.get())
: CreateScopedVideoEncoder( : external_encoder_factory_->CreateVideoEncoder(format);
external_encoder_factory_.get(), codec);
} }
if (internal_encoder && external_encoder) { if (internal_encoder && external_encoder) {
@ -131,34 +165,28 @@ class EncoderAdapter : public webrtc::VideoEncoderFactory {
: std::move(internal_encoder); : std::move(internal_encoder);
} }
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const { std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override {
std::vector<VideoCodec> codecs = std::vector<webrtc::SdpVideoFormat> formats =
InternalEncoderFactory().supported_codecs(); internal_encoder_factory_->GetSupportedFormats();
// Add external codecs. // Add external codecs.
if (external_encoder_factory_ != nullptr) { for (const webrtc::SdpVideoFormat& format :
const std::vector<VideoCodec>& external_codecs = external_encoder_factory_->GetSupportedFormats()) {
external_encoder_factory_->supported_codecs();
for (const VideoCodec& codec : external_codecs) {
// Don't add same codec twice. // Don't add same codec twice.
if (!FindMatchingCodec(codecs, codec)) if (!IsFormatSupported(formats, format))
codecs.push_back(codec); formats.push_back(format);
}
}
std::vector<webrtc::SdpVideoFormat> formats;
for (const VideoCodec& codec : codecs) {
formats.push_back(webrtc::SdpVideoFormat(codec.name, codec.params));
} }
return formats; return formats;
} }
private: private:
const std::unique_ptr<WebRtcVideoEncoderFactory> internal_encoder_factory_; const std::unique_ptr<webrtc::VideoEncoderFactory> internal_encoder_factory_;
const std::unique_ptr<WebRtcVideoEncoderFactory> external_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 { class DecoderAdapter : public webrtc::VideoDecoderFactory {
public: public:
explicit DecoderAdapter( explicit DecoderAdapter(

View File

@ -15,9 +15,10 @@
#include "modules/video_coding/codecs/h264/include/h264.h" #include "modules/video_coding/codecs/h264/include/h264.h"
#include "modules/video_coding/codecs/vp8/include/vp8.h" #include "modules/video_coding/codecs/vp8/include/vp8.h"
#include "modules/video_coding/codecs/vp9/include/vp9.h" #include "modules/video_coding/codecs/vp9/include/vp9.h"
#include "rtc_base/logging.h"
#include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/field_trial.h"
namespace cricket { namespace webrtc {
namespace { namespace {
@ -33,55 +34,55 @@ bool IsFlexfecAdvertisedFieldTrialEnabled() {
} // namespace } // namespace
InternalEncoderFactory::InternalEncoderFactory() { std::vector<SdpVideoFormat> InternalEncoderFactory::GetSupportedFormats()
supported_codecs_.push_back(VideoCodec(kVp8CodecName)); const {
std::vector<SdpVideoFormat> supported_codecs;
supported_codecs.push_back(SdpVideoFormat(cricket::kVp8CodecName));
if (webrtc::VP9Encoder::IsSupported()) if (webrtc::VP9Encoder::IsSupported())
supported_codecs_.push_back(VideoCodec(kVp9CodecName)); supported_codecs.push_back(SdpVideoFormat(cricket::kVp9CodecName));
for (const webrtc::SdpVideoFormat& format : webrtc::SupportedH264Codecs()) 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(SdpVideoFormat(cricket::kRedCodecName));
supported_codecs_.push_back(VideoCodec(kUlpfecCodecName)); supported_codecs.push_back(SdpVideoFormat(cricket::kUlpfecCodecName));
if (IsFlexfecAdvertisedFieldTrialEnabled()) { if (IsFlexfecAdvertisedFieldTrialEnabled()) {
VideoCodec flexfec_codec(kFlexfecCodecName);
// This value is currently arbitrarily set to 10 seconds. (The unit // This value is currently arbitrarily set to 10 seconds. (The unit
// is microseconds.) This parameter MUST be present in the SDP, but // is microseconds.) This parameter MUST be present in the SDP, but
// we never use the actual value anywhere in our code however. // we never use the actual value anywhere in our code however.
// TODO(brandtr): Consider honouring this value in the sender and receiver. // TODO(brandtr): Consider honouring this value in the sender and receiver.
flexfec_codec.SetParam(kFlexfecFmtpRepairWindow, "10000000"); SdpVideoFormat::Parameters params = {
supported_codecs_.push_back(flexfec_codec); {cricket::kFlexfecFmtpRepairWindow, "10000000"}};
} supported_codecs.push_back(
SdpVideoFormat(cricket::kFlexfecCodecName, params));
} }
InternalEncoderFactory::~InternalEncoderFactory() {} return supported_codecs;
}
// WebRtcVideoEncoderFactory implementation. VideoEncoderFactory::CodecInfo InternalEncoderFactory::QueryVideoEncoder(
webrtc::VideoEncoder* InternalEncoderFactory::CreateVideoEncoder( const SdpVideoFormat& format) const {
const VideoCodec& codec) { CodecInfo info;
const webrtc::VideoCodecType codec_type = info.is_hardware_accelerated = false;
webrtc::PayloadStringToCodecType(codec.name); info.has_internal_source = false;
switch (codec_type) { return info;
case webrtc::kVideoCodecH264: }
return webrtc::H264Encoder::Create(codec).release();
case webrtc::kVideoCodecVP8: std::unique_ptr<VideoEncoder> InternalEncoderFactory::CreateVideoEncoder(
return webrtc::VP8Encoder::Create().release(); const SdpVideoFormat& format) {
case webrtc::kVideoCodecVP9: if (cricket::CodecNamesEq(format.name, cricket::kVp8CodecName))
return webrtc::VP9Encoder::Create().release(); return VP8Encoder::Create();
default:
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; return nullptr;
} }
}
const std::vector<VideoCodec>& } // namespace webrtc
InternalEncoderFactory::supported_codecs() const {
return supported_codecs_;
}
void InternalEncoderFactory::DestroyVideoEncoder(
webrtc::VideoEncoder* encoder) {
delete encoder;
}
} // namespace cricket

View File

@ -11,27 +11,23 @@
#ifndef MEDIA_ENGINE_INTERNALENCODERFACTORY_H_ #ifndef MEDIA_ENGINE_INTERNALENCODERFACTORY_H_
#define MEDIA_ENGINE_INTERNALENCODERFACTORY_H_ #define MEDIA_ENGINE_INTERNALENCODERFACTORY_H_
#include <memory>
#include <vector> #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: public:
InternalEncoderFactory(); std::vector<SdpVideoFormat> GetSupportedFormats() const override;
virtual ~InternalEncoderFactory();
// WebRtcVideoEncoderFactory implementation. CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
webrtc::VideoEncoder* CreateVideoEncoder(
const cricket::VideoCodec& codec) override;
const std::vector<cricket::VideoCodec>& supported_codecs() const override;
void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override;
private: std::unique_ptr<VideoEncoder> CreateVideoEncoder(
std::vector<cricket::VideoCodec> supported_codecs_; const SdpVideoFormat& format) override;
}; };
} // namespace cricket } // namespace webrtc
#endif // MEDIA_ENGINE_INTERNALENCODERFACTORY_H_ #endif // MEDIA_ENGINE_INTERNALENCODERFACTORY_H_

View File

@ -16,6 +16,7 @@
#include "libyuv/scale.h" // NOLINT #include "libyuv/scale.h" // NOLINT
#include "api/video/i420_buffer.h" #include "api/video/i420_buffer.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "media/engine/scopedvideoencoder.h" #include "media/engine/scopedvideoencoder.h"
#include "modules/video_coding/codecs/vp8/screenshare_layers.h" #include "modules/video_coding/codecs/vp8/screenshare_layers.h"
#include "modules/video_coding/codecs/vp8/simulcast_rate_allocator.h" #include "modules/video_coding/codecs/vp8/simulcast_rate_allocator.h"
@ -134,10 +135,24 @@ class TemporalLayersFactoryAdapter : public webrtc::TemporalLayersFactory {
namespace webrtc { 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( SimulcastEncoderAdapter::SimulcastEncoderAdapter(
cricket::WebRtcVideoEncoderFactory* factory) cricket::WebRtcVideoEncoderFactory* factory)
: inited_(0), : inited_(0),
factory_(factory), factory_(nullptr),
cricket_factory_(factory),
encoded_complete_callback_(nullptr), encoded_complete_callback_(nullptr),
implementation_name_("SimulcastEncoderAdapter") { implementation_name_("SimulcastEncoderAdapter") {
// The adapter is typically created on the worker thread, but operated on // 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()); encoder = std::move(stored_encoders_.top());
stored_encoders_.pop(); stored_encoders_.pop();
} else { } 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); ret = encoder->InitEncode(&stream_codec, number_of_cores, max_payload_size);

View File

@ -26,6 +26,7 @@
namespace webrtc { namespace webrtc {
class SimulcastRateAllocator; class SimulcastRateAllocator;
class VideoEncoderFactory;
// SimulcastEncoderAdapter implements simulcast support by creating multiple // SimulcastEncoderAdapter implements simulcast support by creating multiple
// webrtc::VideoEncoder instances with the given VideoEncoderFactory. // webrtc::VideoEncoder instances with the given VideoEncoderFactory.
@ -33,6 +34,8 @@ class SimulcastRateAllocator;
// interfaces should be called from the encoder task queue. // interfaces should be called from the encoder task queue.
class SimulcastEncoderAdapter : public VP8Encoder { class SimulcastEncoderAdapter : public VP8Encoder {
public: public:
explicit SimulcastEncoderAdapter(VideoEncoderFactory* factory);
// Deprecated - use webrtc::VideoEncoderFactory instead.
explicit SimulcastEncoderAdapter(cricket::WebRtcVideoEncoderFactory* factory); explicit SimulcastEncoderAdapter(cricket::WebRtcVideoEncoderFactory* factory);
virtual ~SimulcastEncoderAdapter(); virtual ~SimulcastEncoderAdapter();
@ -96,7 +99,8 @@ class SimulcastEncoderAdapter : public VP8Encoder {
void DestroyStoredEncoders(); void DestroyStoredEncoders();
volatile int inited_; // Accessed atomically. volatile int inited_; // Accessed atomically.
cricket::WebRtcVideoEncoderFactory* const factory_; VideoEncoderFactory* const factory_;
cricket::WebRtcVideoEncoderFactory* const cricket_factory_;
VideoCodec codec_; VideoCodec codec_;
std::vector<StreamInfo> streaminfos_; std::vector<StreamInfo> streaminfos_;
EncodedImageCallback* encoded_complete_callback_; EncodedImageCallback* encoded_complete_callback_;

View File

@ -12,6 +12,8 @@
#include <memory> #include <memory>
#include <vector> #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 "common_video/include/video_frame_buffer.h"
#include "media/engine/internalencoderfactory.h" #include "media/engine/internalencoderfactory.h"
#include "media/engine/simulcast_encoder_adapter.h" #include "media/engine/simulcast_encoder_adapter.h"
@ -25,8 +27,7 @@ namespace testing {
class TestSimulcastEncoderAdapter : public TestVp8Simulcast { class TestSimulcastEncoderAdapter : public TestVp8Simulcast {
public: public:
TestSimulcastEncoderAdapter() TestSimulcastEncoderAdapter() : factory_(new InternalEncoderFactory()) {}
: factory_(new cricket::InternalEncoderFactory()) {}
protected: protected:
std::unique_ptr<VP8Encoder> CreateEncoder() override { std::unique_ptr<VP8Encoder> CreateEncoder() override {
@ -37,7 +38,7 @@ class TestSimulcastEncoderAdapter : public TestVp8Simulcast {
} }
private: private:
std::unique_ptr<cricket::WebRtcVideoEncoderFactory> factory_; std::unique_ptr<VideoEncoderFactory> factory_;
}; };
TEST_F(TestSimulcastEncoderAdapter, TestKeyFrameRequestsOnAllStreams) { TEST_F(TestSimulcastEncoderAdapter, TestKeyFrameRequestsOnAllStreams) {
@ -92,8 +93,34 @@ TEST_F(TestSimulcastEncoderAdapter, TestSpatioTemporalLayers321PatternEncoder) {
TestVp8Simulcast::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 { class MockVideoEncoder : public VideoEncoder {
public: public:
explicit MockVideoEncoder(MockVideoEncoderFactory* factory)
: factory_(factory) {}
// TODO(nisse): Valid overrides commented out, because the gmock // TODO(nisse): Valid overrides commented out, because the gmock
// methods don't use any override declarations, and we want to avoid // methods don't use any override declarations, and we want to avoid
// warnings from -Winconsistent-missing-override. See // warnings from -Winconsistent-missing-override. See
@ -131,7 +158,7 @@ class MockVideoEncoder : public VideoEncoder {
return supports_native_handle_; return supports_native_handle_;
} }
virtual ~MockVideoEncoder() {} virtual ~MockVideoEncoder() { factory_->DestroyVideoEncoder(this); }
const VideoCodec& codec() const { return codec_; } const VideoCodec& codec() const { return codec_; }
@ -158,6 +185,7 @@ class MockVideoEncoder : public VideoEncoder {
MOCK_CONST_METHOD0(ImplementationName, const char*()); MOCK_CONST_METHOD0(ImplementationName, const char*());
private: private:
MockVideoEncoderFactory* const factory_;
bool supports_native_handle_ = false; bool supports_native_handle_ = false;
int32_t init_encode_return_value_ = 0; int32_t init_encode_return_value_ = 0;
BitrateAllocation last_set_bitrate_; BitrateAllocation last_set_bitrate_;
@ -166,54 +194,51 @@ class MockVideoEncoder : public VideoEncoder {
EncodedImageCallback* callback_; EncodedImageCallback* callback_;
}; };
class MockVideoEncoderFactory : public cricket::WebRtcVideoEncoderFactory { std::vector<SdpVideoFormat> MockVideoEncoderFactory::GetSupportedFormats()
public: const {
MockVideoEncoderFactory() { std::vector<SdpVideoFormat> formats = {SdpVideoFormat("VP8")};
supported_codecs_.push_back(cricket::VideoCodec("VP8")); return formats;
} }
const std::vector<cricket::VideoCodec>& supported_codecs() const override { std::unique_ptr<VideoEncoder> MockVideoEncoderFactory::CreateVideoEncoder(
return supported_codecs_; const SdpVideoFormat& format) {
} std::unique_ptr<MockVideoEncoder> encoder(
new ::testing::NiceMock<MockVideoEncoder>(this));
VideoEncoder* CreateVideoEncoder(const cricket::VideoCodec& codec) override {
MockVideoEncoder* encoder = new ::testing::NiceMock<MockVideoEncoder>();
encoder->set_init_encode_return_value(init_encode_return_value_); encoder->set_init_encode_return_value(init_encode_return_value_);
const char* encoder_name = encoder_names_.empty() const char* encoder_name = encoder_names_.empty()
? "codec_implementation_name" ? "codec_implementation_name"
: encoder_names_[encoders_.size()]; : encoder_names_[encoders_.size()];
ON_CALL(*encoder, ImplementationName()).WillByDefault(Return(encoder_name)); ON_CALL(*encoder, ImplementationName()).WillByDefault(Return(encoder_name));
encoders_.push_back(encoder); encoders_.push_back(encoder.get());
return encoder; return encoder;
} }
void DestroyVideoEncoder(VideoEncoder* encoder) override { void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
for (size_t i = 0; i < encoders_.size(); ++i) { for (size_t i = 0; i < encoders_.size(); ++i) {
if (encoders_[i] == encoder) { if (encoders_[i] == encoder) {
encoders_.erase(encoders_.begin() + i); encoders_.erase(encoders_.begin() + i);
break; break;
} }
} }
delete encoder;
} }
virtual ~MockVideoEncoderFactory() {} VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
const SdpVideoFormat& format) const {
return CodecInfo();
}
const std::vector<MockVideoEncoder*>& encoders() const { return encoders_; } const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
void SetEncoderNames(const std::vector<const char*>& encoder_names) { const {
return encoders_;
}
void MockVideoEncoderFactory::SetEncoderNames(
const std::vector<const char*>& encoder_names) {
encoder_names_ = 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; 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 { class TestSimulcastEncoderAdapterFakeHelper {
public: public:
TestSimulcastEncoderAdapterFakeHelper() TestSimulcastEncoderAdapterFakeHelper()

View File

@ -15,10 +15,9 @@
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
namespace webrtc { namespace webrtc {
VP8EncoderSimulcastProxy::VP8EncoderSimulcastProxy( VP8EncoderSimulcastProxy::VP8EncoderSimulcastProxy(VideoEncoderFactory* factory)
cricket::WebRtcVideoEncoderFactory* factory)
: factory_(factory), callback_(nullptr) { : factory_(factory), callback_(nullptr) {
encoder_ = CreateScopedVideoEncoder(factory_, cricket::VideoCodec("VP8")); encoder_ = factory_->CreateVideoEncoder(SdpVideoFormat("VP8"));
} }
VP8EncoderSimulcastProxy::~VP8EncoderSimulcastProxy() {} VP8EncoderSimulcastProxy::~VP8EncoderSimulcastProxy() {}

View File

@ -15,7 +15,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "media/engine/webrtcvideoencoderfactory.h" #include "api/video_codecs/video_encoder_factory.h"
#include "modules/video_coding/codecs/vp8/include/vp8.h" #include "modules/video_coding/codecs/vp8/include/vp8.h"
namespace webrtc { namespace webrtc {
@ -24,8 +24,7 @@ namespace webrtc {
// doesn't support simulcast for provided settings. // doesn't support simulcast for provided settings.
class VP8EncoderSimulcastProxy : public VP8Encoder { class VP8EncoderSimulcastProxy : public VP8Encoder {
public: public:
explicit VP8EncoderSimulcastProxy( explicit VP8EncoderSimulcastProxy(VideoEncoderFactory* factory);
cricket::WebRtcVideoEncoderFactory* factory);
virtual ~VP8EncoderSimulcastProxy(); virtual ~VP8EncoderSimulcastProxy();
// Implements VideoEncoder. // Implements VideoEncoder.
@ -48,7 +47,7 @@ class VP8EncoderSimulcastProxy : public VP8Encoder {
const char* ImplementationName() const override; const char* ImplementationName() const override;
private: private:
cricket::WebRtcVideoEncoderFactory* const factory_; VideoEncoderFactory* const factory_;
std::unique_ptr<VideoEncoder> encoder_; std::unique_ptr<VideoEncoder> encoder_;
EncodedImageCallback* callback_; EncodedImageCallback* callback_;
}; };

View File

@ -13,6 +13,7 @@
#include <string> #include <string>
#include "api/test/mock_video_encoder_factory.h"
#include "media/engine/webrtcvideoencoderfactory.h" #include "media/engine/webrtcvideoencoderfactory.h"
#include "modules/video_coding/codecs/vp8/temporal_layers.h" #include "modules/video_coding/codecs/vp8/temporal_layers.h"
#include "modules/video_coding/include/video_codec_interface.h" #include "modules/video_coding/include/video_codec_interface.h"
@ -56,20 +57,6 @@ class MockEncoder : public VideoEncoder {
MOCK_CONST_METHOD0(ImplementationName, const char*()); 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) { TEST(VP8EncoderSimulcastProxy, ChoosesCorrectImplementation) {
const std::string kImplementationName = "Fake"; const std::string kImplementationName = "Fake";
const std::string kSimulcastAdaptedImplementationName = const std::string kSimulcastAdaptedImplementationName =
@ -86,56 +73,56 @@ TEST(VP8EncoderSimulcastProxy, ChoosesCorrectImplementation) {
test::kTestWidth, test::kTestHeight, 2, 5000, 1000, 1000, 56}; test::kTestWidth, test::kTestHeight, 2, 5000, 1000, 1000, 56};
codec_settings.numberOfSimulcastStreams = 3; codec_settings.numberOfSimulcastStreams = 3;
NiceMock<MockEncoder> mock_encoder; NiceMock<MockEncoder>* mock_encoder = new NiceMock<MockEncoder>();
NiceMock<MockWebRtcVideoEncoderFactory> 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(mock_encoder, ImplementationName()) EXPECT_CALL(*mock_encoder, ImplementationName())
.WillRepeatedly(Return(kImplementationName.c_str())); .WillRepeatedly(Return(kImplementationName.c_str()));
EXPECT_CALL(simulcast_factory, CreateVideoEncoder(_)) EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_))
.Times(1) .Times(1)
.WillOnce(Return(&mock_encoder)); .WillOnce(Return(mock_encoder));
VP8EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory); VP8EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory);
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, 4, 1200));
EXPECT_EQ(kImplementationName, simulcast_enabled_proxy.ImplementationName()); EXPECT_EQ(kImplementationName, simulcast_enabled_proxy.ImplementationName());
NiceMock<MockEncoder> mock_encoder1; NiceMock<MockEncoder>* mock_encoder1 = new NiceMock<MockEncoder>();
NiceMock<MockEncoder> mock_encoder2; NiceMock<MockEncoder>* mock_encoder2 = new NiceMock<MockEncoder>();
NiceMock<MockEncoder> mock_encoder3; NiceMock<MockEncoder>* mock_encoder3 = new NiceMock<MockEncoder>();
NiceMock<MockEncoder> mock_encoder4; NiceMock<MockEncoder>* mock_encoder4 = new NiceMock<MockEncoder>();
NiceMock<MockWebRtcVideoEncoderFactory> 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, ImplementationName()) EXPECT_CALL(*mock_encoder1, ImplementationName())
.WillRepeatedly(Return(kImplementationName.c_str())); .WillRepeatedly(Return(kImplementationName.c_str()));
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, ImplementationName()) EXPECT_CALL(*mock_encoder2, ImplementationName())
.WillRepeatedly(Return(kImplementationName.c_str())); .WillRepeatedly(Return(kImplementationName.c_str()));
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, ImplementationName()) EXPECT_CALL(*mock_encoder3, ImplementationName())
.WillRepeatedly(Return(kImplementationName.c_str())); .WillRepeatedly(Return(kImplementationName.c_str()));
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, ImplementationName()) EXPECT_CALL(*mock_encoder4, ImplementationName())
.WillRepeatedly(Return(kImplementationName.c_str())); .WillRepeatedly(Return(kImplementationName.c_str()));
EXPECT_CALL(nonsimulcast_factory, CreateVideoEncoder(_)) EXPECT_CALL(nonsimulcast_factory, CreateVideoEncoderProxy(_))
.Times(4) .Times(4)
.WillOnce(Return(&mock_encoder1)) .WillOnce(Return(mock_encoder1))
.WillOnce(Return(&mock_encoder2)) .WillOnce(Return(mock_encoder2))
.WillOnce(Return(&mock_encoder3)) .WillOnce(Return(mock_encoder3))
.WillOnce(Return(&mock_encoder4)); .WillOnce(Return(mock_encoder4));
VP8EncoderSimulcastProxy simulcast_disabled_proxy(&nonsimulcast_factory); VP8EncoderSimulcastProxy simulcast_disabled_proxy(&nonsimulcast_factory);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,

View File

@ -80,6 +80,40 @@ bool RunEncodeInRealTime(const TestConfig& config) {
#endif #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. // An internal decoder factory in the old WebRtcVideoDecoderFactory format.
// TODO(magjed): Update these tests to use new webrtc::VideoDecoderFactory // TODO(magjed): Update these tests to use new webrtc::VideoDecoderFactory
// instead. // instead.
@ -313,7 +347,7 @@ void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() {
RTC_NOTREACHED() << "Only support HW encoder on Android and iOS."; RTC_NOTREACHED() << "Only support HW encoder on Android and iOS.";
#endif #endif
} else { } else {
encoder_factory.reset(new cricket::InternalEncoderFactory()); encoder_factory.reset(new LegacyInternalEncoderFactory());
} }
std::unique_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory; std::unique_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory;
@ -382,8 +416,8 @@ void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() {
if (config_.sw_fallback_encoder) { if (config_.sw_fallback_encoder) {
encoder_ = rtc::MakeUnique<VideoEncoderSoftwareFallbackWrapper>( encoder_ = rtc::MakeUnique<VideoEncoderSoftwareFallbackWrapper>(
std::unique_ptr<VideoEncoder>( InternalEncoderFactory().CreateVideoEncoder(
cricket::InternalEncoderFactory().CreateVideoEncoder(codec)), SdpVideoFormat(codec.name, codec.params)),
std::move(encoder_)); std::move(encoder_));
} }
if (config_.sw_fallback_decoder) { if (config_.sw_fallback_decoder) {

View File

@ -516,11 +516,21 @@ bool MediaCodecVideoEncoder::EncodeTask::Run() {
return false; 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 MediaCodecVideoEncoder::ProcessHWError(
bool reset_if_fallback_unavailable) { bool reset_if_fallback_unavailable) {
ALOGE << "ProcessHWError"; ALOGE << "ProcessHWError";
if (FindMatchingCodec(cricket::InternalEncoderFactory().supported_codecs(), if (IsFormatSupported(InternalEncoderFactory().GetSupportedFormats(),
codec_)) { codec_.name)) {
ALOGE << "Fallback to SW encoder."; ALOGE << "Fallback to SW encoder.";
sw_fallback_required_ = true; sw_fallback_required_ = true;
return false; return false;

View File

@ -346,7 +346,7 @@ TEST_P(PictureIdTest, PictureIdIncreasingAfterStreamCountChangeVp8) {
TEST_P(PictureIdTest, TEST_P(PictureIdTest,
PictureIdContinuousAfterReconfigureSimulcastEncoderAdapter) { PictureIdContinuousAfterReconfigureSimulcastEncoderAdapter) {
cricket::InternalEncoderFactory internal_encoder_factory; InternalEncoderFactory internal_encoder_factory;
SimulcastEncoderAdapter simulcast_encoder_adapter(&internal_encoder_factory); SimulcastEncoderAdapter simulcast_encoder_adapter(&internal_encoder_factory);
SetupEncoder(&simulcast_encoder_adapter); SetupEncoder(&simulcast_encoder_adapter);
TestPictureIdContinuousAfterReconfigure({1, 3, 3, 1, 1}); TestPictureIdContinuousAfterReconfigure({1, 3, 3, 1, 1});
@ -354,7 +354,7 @@ TEST_P(PictureIdTest,
TEST_P(PictureIdTest, TEST_P(PictureIdTest,
PictureIdIncreasingAfterRecreateStreamSimulcastEncoderAdapter) { PictureIdIncreasingAfterRecreateStreamSimulcastEncoderAdapter) {
cricket::InternalEncoderFactory internal_encoder_factory; InternalEncoderFactory internal_encoder_factory;
SimulcastEncoderAdapter simulcast_encoder_adapter(&internal_encoder_factory); SimulcastEncoderAdapter simulcast_encoder_adapter(&internal_encoder_factory);
SetupEncoder(&simulcast_encoder_adapter); SetupEncoder(&simulcast_encoder_adapter);
TestPictureIdIncreaseAfterRecreateStreams({1, 3, 3, 1, 1}); 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 // If forced fallback is enabled, the picture id is set in the PayloadRouter
// and the sequence should be continuous. // and the sequence should be continuous.
if (GetParam() == kVp8ForcedFallbackEncoderEnabled) { if (GetParam() == kVp8ForcedFallbackEncoderEnabled) {
cricket::InternalEncoderFactory internal_encoder_factory; InternalEncoderFactory internal_encoder_factory;
SimulcastEncoderAdapter simulcast_encoder_adapter( SimulcastEncoderAdapter simulcast_encoder_adapter(
&internal_encoder_factory); &internal_encoder_factory);
// Make sure that that the picture id is not reset if the stream count goes // Make sure that that the picture id is not reset if the stream count goes

View File

@ -13,7 +13,6 @@
#include <algorithm> #include <algorithm>
#include <deque> #include <deque>
#include <map> #include <map>
#include <set>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
@ -1393,7 +1392,7 @@ void VideoQualityTest::SetupVideo(Transport* send_transport,
// encoders usually can't natively do simulcast with different frame rates // encoders usually can't natively do simulcast with different frame rates
// for the different layers. // for the different layers.
video_encoder_.reset( video_encoder_.reset(
new SimulcastEncoderAdapter(new cricket::InternalEncoderFactory())); new SimulcastEncoderAdapter(new InternalEncoderFactory()));
} else { } else {
video_encoder_ = VP8Encoder::Create(); 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::vector<std::unique_ptr<test::VideoCapturer>> thumbnail_capturers_;
std::unique_ptr<test::FrameGenerator> frame_generator_; std::unique_ptr<test::FrameGenerator> frame_generator_;
std::unique_ptr<VideoEncoder> video_encoder_; std::unique_ptr<VideoEncoder> video_encoder_;
std::unique_ptr<cricket::WebRtcVideoEncoderFactory> vp8_encoder_factory_;
std::vector<std::unique_ptr<VideoEncoder>> thumbnail_encoders_; std::vector<std::unique_ptr<VideoEncoder>> thumbnail_encoders_;
std::vector<VideoSendStream::Config> thumbnail_send_configs_; std::vector<VideoSendStream::Config> thumbnail_send_configs_;