From 65e15bafaaf18a5361a9831b17254810d5cb3111 Mon Sep 17 00:00:00 2001 From: pbos Date: Thu, 15 Oct 2015 10:52:15 -0700 Subject: [PATCH] Add native-handle support for single VP8 streams. Implements SupportsNativeHandle() in SimulcastEncoderAdapter which works when there's only a single encoder. BUG=webrtc:5060 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/1397653004 Cr-Commit-Position: refs/heads/master@{#10291} --- .../codecs/vp8/simulcast_encoder_adapter.cc | 10 ++++ .../codecs/vp8/simulcast_encoder_adapter.h | 1 + .../vp8/simulcast_encoder_adapter_unittest.cc | 48 +++++++++++++++++-- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc b/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc index 1b59be3536..9ac2efabe6 100644 --- a/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc +++ b/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc @@ -15,6 +15,7 @@ // NOTE(ajm): Path provided by gyp. #include "libyuv/scale.h" // NOLINT +#include "webrtc/base/checks.h" #include "webrtc/common.h" #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h" @@ -497,4 +498,13 @@ int SimulcastEncoderAdapter::GetTargetFramerate() { return streaminfos_[0].encoder->GetTargetFramerate(); } +bool SimulcastEncoderAdapter::SupportsNativeHandle() const { + // We should not be calling this method before streaminfos_ are configured. + RTC_DCHECK(!streaminfos_.empty()); + // TODO(pbos): Support textures when using more than one encoder. + if (streaminfos_.size() != 1) + return false; + return streaminfos_[0].encoder->SupportsNativeHandle(); +} + } // namespace webrtc diff --git a/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h b/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h index bca1e00a71..c00d8fb80a 100644 --- a/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h +++ b/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h @@ -58,6 +58,7 @@ class SimulcastEncoderAdapter : public VP8Encoder { void OnDroppedFrame() override; int GetTargetFramerate() override; + bool SupportsNativeHandle() const override; private: struct StreamInfo { diff --git a/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter_unittest.cc b/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter_unittest.cc index 7dc75ed9e3..ed6541c3a8 100644 --- a/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter_unittest.cc +++ b/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter_unittest.cc @@ -110,33 +110,38 @@ class MockVideoEncoder : public VideoEncoder { public: int32_t InitEncode(const VideoCodec* codecSettings, int32_t numberOfCores, - size_t maxPayloadSize) { + size_t maxPayloadSize) override { codec_ = *codecSettings; return 0; } int32_t Encode(const VideoFrame& inputImage, const CodecSpecificInfo* codecSpecificInfo, - const std::vector* frame_types) { + const std::vector* frame_types) override { return 0; } - int32_t RegisterEncodeCompleteCallback(EncodedImageCallback* callback) { + int32_t RegisterEncodeCompleteCallback( + EncodedImageCallback* callback) override { callback_ = callback; return 0; } - int32_t Release() { + int32_t Release() override { return 0; } - int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) { + int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override { return 0; } MOCK_METHOD2(SetChannelParameters, int32_t(uint32_t packetLoss, int64_t rtt)); + bool SupportsNativeHandle() const override { + return supports_native_handle_; + } + virtual ~MockVideoEncoder() { } @@ -152,7 +157,12 @@ class MockVideoEncoder : public VideoEncoder { callback_->Encoded(image, &codecSpecificInfo, NULL); } + void set_supports_native_handle(bool enabled) { + supports_native_handle_ = enabled; + } + private: + bool supports_native_handle_ = false; VideoCodec codec_; EncodedImageCallback* callback_; }; @@ -382,5 +392,33 @@ TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) { EXPECT_EQ(2, simulcast_index); } +TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) { + TestVp8Simulcast::DefaultSettings( + &codec_, static_cast(kTestTemporalLayerProfile)); + codec_.numberOfSimulcastStreams = 1; + EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + adapter_->RegisterEncodeCompleteCallback(this); + ASSERT_EQ(1u, helper_->factory()->encoders().size()); + helper_->factory()->encoders()[0]->set_supports_native_handle(true); + EXPECT_TRUE(adapter_->SupportsNativeHandle()); + helper_->factory()->encoders()[0]->set_supports_native_handle(false); + EXPECT_FALSE(adapter_->SupportsNativeHandle()); +} + +TEST_F(TestSimulcastEncoderAdapterFake, + SupportsNativeHandleDisabledForMultipleStreams) { + // TODO(pbos): Implement actual test (verify that it works) when implemented + // for multiple streams. + TestVp8Simulcast::DefaultSettings( + &codec_, static_cast(kTestTemporalLayerProfile)); + codec_.numberOfSimulcastStreams = 3; + EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200)); + adapter_->RegisterEncodeCompleteCallback(this); + ASSERT_EQ(3u, helper_->factory()->encoders().size()); + for (MockVideoEncoder* encoder : helper_->factory()->encoders()) + encoder->set_supports_native_handle(true); + EXPECT_FALSE(adapter_->SupportsNativeHandle()); +} + } // namespace testing } // namespace webrtc