Reason for revert: Should work after cl https://codereview.webrtc.org/1985693002/ is landed, which initializes the frames used by FakeWebRtcVideoCaptureModule. So intend to reland after that, with no changes. Original issue's description: > Revert of Delete webrtc::VideoFrame methods buffer and stride. (patchset #2 id:290001 of https://codereview.webrtc.org/1963413004/ ) > > Reason for revert: > Speculative revert to see if failures on the DrMemory bot are related to this cl. See e.g. here: > https://build.chromium.org/p/client.webrtc/builders/Win%20DrMemory%20Full/builds/4243 > > UNINITIALIZED READ: reading 0x04980040-0x04980060 32 byte(s) within 0x04980040-0x04980060 > # 0 CopyRow_AVX > # 1 CopyPlane > # 2 I420Copy > # 3 webrtc::ExtractBuffer > # 4 cricket::WebRtcVideoCapturer::SignalFrameCapturedOnStartThread > # 5 cricket::WebRtcVideoCapturer::OnIncomingCapturedFrame > # 6 FakeWebRtcVideoCaptureModule::SendFrame > # 7 WebRtcVideoCapturerTest_TestCaptureVcm_Test::TestBody > # 8 testing::internal::HandleSehExceptionsInMethodIfSupported<> > > Original issue's description: > > Reland of Delete webrtc::VideoFrame methods buffer and stride. (patchset #1 id:1 of https://codereview.webrtc.org/1935443002/ ) > > > > Reason for revert: > > I plan to reland this change in a week or two, after downstream users are updated. > > > > Original issue's description: > > > Revert of Delete webrtc::VideoFrame methods buffer and stride. (patchset #14 id:250001 of https://codereview.webrtc.org/1900673002/ ) > > > > > > Reason for revert: > > > Breaks chrome FYI bots. > > > > > > Original issue's description: > > > > Delete webrtc::VideoFrame methods buffer and stride. > > > > > > > > To make the HasOneRef/IsMutable hack work, also had to change the > > > > video_frame_buffer method to return a const ref to a scoped_ref_ptr, > > > > to not imply an AddRef. > > > > > > > > BUG=webrtc:5682 > > > > > > TBR=perkj@webrtc.org,magjed@webrtc.org,pbos@webrtc.org,pthatcher@webrtc.org,stefan@webrtc.org > > > # Skipping CQ checks because original CL landed less than 1 days ago. > > > NOPRESUBMIT=true > > > NOTREECHECKS=true > > > NOTRY=true > > > BUG=webrtc:5682 > > > > > > Committed: https://crrev.com/5b3c443d301f2c2f18dac5b02652c08b91ea3828 > > > Cr-Commit-Position: refs/heads/master@{#12558} > > > > TBR=perkj@webrtc.org,magjed@webrtc.org,pbos@webrtc.org,pthatcher@webrtc.org,stefan@webrtc.org > > # Not skipping CQ checks because original CL landed more than 1 days ago. > > BUG=webrtc:5682 > > > > Committed: https://crrev.com/d0dc66e0ea30c8614001e425a4ae0aa7dd56c2a7 > > Cr-Commit-Position: refs/heads/master@{#12721} > > TBR=perkj@webrtc.org,magjed@webrtc.org,pbos@webrtc.org,pthatcher@webrtc.org,stefan@webrtc.org,nisse@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:5682 > > Committed: https://crrev.com/d49c30cd2fe442f2b5b4ecec8d5cbaa430464725 > Cr-Commit-Position: refs/heads/master@{#12745} TBR=perkj@webrtc.org,magjed@webrtc.org,pbos@webrtc.org,pthatcher@webrtc.org,stefan@webrtc.org,tommi@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:5682 Review-Url: https://codereview.webrtc.org/1979193003 Cr-Commit-Position: refs/heads/master@{#12773}
276 lines
9.7 KiB
C++
276 lines
9.7 KiB
C++
/*
|
|
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "webrtc/video_encoder.h"
|
|
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
#include "webrtc/modules/video_coding/include/video_error_codes.h"
|
|
|
|
namespace webrtc {
|
|
|
|
const int kWidth = 320;
|
|
const int kHeight = 240;
|
|
const size_t kMaxPayloadSize = 800;
|
|
|
|
class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
|
|
protected:
|
|
VideoEncoderSoftwareFallbackWrapperTest()
|
|
: fallback_wrapper_(kVideoCodecVP8, &fake_encoder_) {}
|
|
|
|
class CountingFakeEncoder : public VideoEncoder {
|
|
public:
|
|
int32_t InitEncode(const VideoCodec* codec_settings,
|
|
int32_t number_of_cores,
|
|
size_t max_payload_size) override {
|
|
++init_encode_count_;
|
|
return init_encode_return_code_;
|
|
}
|
|
int32_t Encode(const VideoFrame& frame,
|
|
const CodecSpecificInfo* codec_specific_info,
|
|
const std::vector<FrameType>* frame_types) override {
|
|
++encode_count_;
|
|
return encode_return_code_;
|
|
}
|
|
|
|
int32_t RegisterEncodeCompleteCallback(
|
|
EncodedImageCallback* callback) override {
|
|
encode_complete_callback_ = callback;
|
|
return WEBRTC_VIDEO_CODEC_OK;
|
|
}
|
|
|
|
int32_t Release() override {
|
|
++release_count_;
|
|
return WEBRTC_VIDEO_CODEC_OK;
|
|
}
|
|
|
|
int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) override {
|
|
++set_channel_parameters_count_;
|
|
return WEBRTC_VIDEO_CODEC_OK;
|
|
}
|
|
|
|
int32_t SetRates(uint32_t bitrate, uint32_t framerate) override {
|
|
++set_rates_count_;
|
|
return WEBRTC_VIDEO_CODEC_OK;
|
|
}
|
|
|
|
void OnDroppedFrame() override { ++on_dropped_frame_count_; }
|
|
|
|
bool SupportsNativeHandle() const override {
|
|
++supports_native_handle_count_;
|
|
return false;
|
|
}
|
|
|
|
const char* ImplementationName() const override {
|
|
return "fake-encoder";
|
|
}
|
|
|
|
int init_encode_count_ = 0;
|
|
int32_t init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
|
|
int32_t encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
|
|
int encode_count_ = 0;
|
|
EncodedImageCallback* encode_complete_callback_ = nullptr;
|
|
int release_count_ = 0;
|
|
int set_channel_parameters_count_ = 0;
|
|
int set_rates_count_ = 0;
|
|
int on_dropped_frame_count_ = 0;
|
|
mutable int supports_native_handle_count_ = 0;
|
|
};
|
|
|
|
class FakeEncodedImageCallback : public EncodedImageCallback {
|
|
public:
|
|
int32_t Encoded(const EncodedImage& encoded_image,
|
|
const CodecSpecificInfo* codec_specific_info,
|
|
const RTPFragmentationHeader* fragmentation) override {
|
|
return ++callback_count_;
|
|
}
|
|
int callback_count_ = 0;
|
|
};
|
|
|
|
void UtilizeFallbackEncoder();
|
|
void FallbackFromEncodeRequest();
|
|
void EncodeFrame();
|
|
|
|
FakeEncodedImageCallback callback_;
|
|
CountingFakeEncoder fake_encoder_;
|
|
VideoEncoderSoftwareFallbackWrapper fallback_wrapper_;
|
|
VideoCodec codec_ = {};
|
|
VideoFrame frame_;
|
|
};
|
|
|
|
void VideoEncoderSoftwareFallbackWrapperTest::EncodeFrame() {
|
|
frame_.CreateEmptyFrame(kWidth, kHeight, kWidth, (kWidth + 1) / 2,
|
|
(kWidth + 1) / 2);
|
|
memset(frame_.video_frame_buffer()->MutableDataY(), 16,
|
|
frame_.allocated_size(webrtc::kYPlane));
|
|
memset(frame_.video_frame_buffer()->MutableDataU(), 128,
|
|
frame_.allocated_size(webrtc::kUPlane));
|
|
memset(frame_.video_frame_buffer()->MutableDataV(), 128,
|
|
frame_.allocated_size(webrtc::kVPlane));
|
|
|
|
std::vector<FrameType> types(1, kVideoFrameKey);
|
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
|
fallback_wrapper_.Encode(frame_, nullptr, &types));
|
|
}
|
|
|
|
void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() {
|
|
fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_);
|
|
EXPECT_EQ(&callback_, fake_encoder_.encode_complete_callback_);
|
|
|
|
// Register with failing fake encoder. Should succeed with VP8 fallback.
|
|
codec_.codecType = kVideoCodecVP8;
|
|
codec_.maxFramerate = 30;
|
|
codec_.width = kWidth;
|
|
codec_.height = kHeight;
|
|
fake_encoder_.init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
|
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
|
fallback_wrapper_.InitEncode(&codec_, 2, kMaxPayloadSize));
|
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.SetRates(300, 30));
|
|
|
|
int callback_count = callback_.callback_count_;
|
|
int encode_count = fake_encoder_.encode_count_;
|
|
EncodeFrame();
|
|
EXPECT_EQ(encode_count, fake_encoder_.encode_count_);
|
|
EXPECT_EQ(callback_count + 1, callback_.callback_count_);
|
|
}
|
|
|
|
void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() {
|
|
fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_);
|
|
codec_.codecType = kVideoCodecVP8;
|
|
codec_.maxFramerate = 30;
|
|
codec_.width = kWidth;
|
|
codec_.height = kHeight;
|
|
fallback_wrapper_.InitEncode(&codec_, 2, kMaxPayloadSize);
|
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.SetRates(300, 30));
|
|
EXPECT_EQ(1, fake_encoder_.init_encode_count_);
|
|
|
|
// Have the non-fallback encoder request a software fallback.
|
|
fake_encoder_.encode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
|
|
int callback_count = callback_.callback_count_;
|
|
int encode_count = fake_encoder_.encode_count_;
|
|
EncodeFrame();
|
|
// Single encode request, which returned failure.
|
|
EXPECT_EQ(encode_count + 1, fake_encoder_.encode_count_);
|
|
EXPECT_EQ(callback_count + 1, callback_.callback_count_);
|
|
}
|
|
|
|
TEST_F(VideoEncoderSoftwareFallbackWrapperTest, InitializesEncoder) {
|
|
VideoCodec codec = {};
|
|
fallback_wrapper_.InitEncode(&codec, 2, kMaxPayloadSize);
|
|
EXPECT_EQ(1, fake_encoder_.init_encode_count_);
|
|
}
|
|
|
|
TEST_F(VideoEncoderSoftwareFallbackWrapperTest, EncodeRequestsFallback) {
|
|
FallbackFromEncodeRequest();
|
|
// After fallback, further encodes shouldn't hit the fake encoder.
|
|
int encode_count = fake_encoder_.encode_count_;
|
|
EncodeFrame();
|
|
EXPECT_EQ(encode_count, fake_encoder_.encode_count_);
|
|
}
|
|
|
|
TEST_F(VideoEncoderSoftwareFallbackWrapperTest, CanUtilizeFallbackEncoder) {
|
|
UtilizeFallbackEncoder();
|
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
|
|
}
|
|
|
|
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
|
|
InternalEncoderReleasedDuringFallback) {
|
|
EXPECT_EQ(0, fake_encoder_.release_count_);
|
|
UtilizeFallbackEncoder();
|
|
EXPECT_EQ(1, fake_encoder_.release_count_);
|
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
|
|
// No extra release when the fallback is released.
|
|
EXPECT_EQ(1, fake_encoder_.release_count_);
|
|
}
|
|
|
|
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
|
|
InternalEncoderNotEncodingDuringFallback) {
|
|
UtilizeFallbackEncoder();
|
|
int encode_count = fake_encoder_.encode_count_;
|
|
EncodeFrame();
|
|
EXPECT_EQ(encode_count, fake_encoder_.encode_count_);
|
|
|
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
|
|
}
|
|
|
|
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
|
|
CanRegisterCallbackWhileUsingFallbackEncoder) {
|
|
UtilizeFallbackEncoder();
|
|
// Registering an encode-complete callback should still work when fallback
|
|
// encoder is being used.
|
|
FakeEncodedImageCallback callback2;
|
|
fallback_wrapper_.RegisterEncodeCompleteCallback(&callback2);
|
|
EXPECT_EQ(&callback2, fake_encoder_.encode_complete_callback_);
|
|
|
|
// Encoding a frame using the fallback should arrive at the new callback.
|
|
std::vector<FrameType> types(1, kVideoFrameKey);
|
|
frame_.set_timestamp(frame_.timestamp() + 1000);
|
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
|
fallback_wrapper_.Encode(frame_, nullptr, &types));
|
|
|
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
|
|
}
|
|
|
|
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
|
|
SetChannelParametersForwardedDuringFallback) {
|
|
UtilizeFallbackEncoder();
|
|
EXPECT_EQ(0, fake_encoder_.set_channel_parameters_count_);
|
|
fallback_wrapper_.SetChannelParameters(1, 1);
|
|
EXPECT_EQ(1, fake_encoder_.set_channel_parameters_count_);
|
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
|
|
}
|
|
|
|
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
|
|
SetRatesForwardedDuringFallback) {
|
|
UtilizeFallbackEncoder();
|
|
EXPECT_EQ(1, fake_encoder_.set_rates_count_);
|
|
fallback_wrapper_.SetRates(1, 1);
|
|
EXPECT_EQ(2, fake_encoder_.set_rates_count_);
|
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
|
|
}
|
|
|
|
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
|
|
OnDroppedFrameForwardedWithoutFallback) {
|
|
fallback_wrapper_.OnDroppedFrame();
|
|
EXPECT_EQ(1, fake_encoder_.on_dropped_frame_count_);
|
|
}
|
|
|
|
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
|
|
OnDroppedFrameNotForwardedDuringFallback) {
|
|
UtilizeFallbackEncoder();
|
|
fallback_wrapper_.OnDroppedFrame();
|
|
EXPECT_EQ(0, fake_encoder_.on_dropped_frame_count_);
|
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
|
|
}
|
|
|
|
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
|
|
SupportsNativeHandleForwardedWithoutFallback) {
|
|
fallback_wrapper_.SupportsNativeHandle();
|
|
EXPECT_EQ(1, fake_encoder_.supports_native_handle_count_);
|
|
}
|
|
|
|
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
|
|
SupportsNativeHandleNotForwardedDuringFallback) {
|
|
UtilizeFallbackEncoder();
|
|
fallback_wrapper_.SupportsNativeHandle();
|
|
EXPECT_EQ(0, fake_encoder_.supports_native_handle_count_);
|
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
|
|
}
|
|
|
|
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
|
|
ReportsFallbackImplementationName) {
|
|
UtilizeFallbackEncoder();
|
|
// Hard coded expected value since libvpx is the software implementation name
|
|
// for VP8. Change accordingly if the underlying implementation does.
|
|
EXPECT_STREQ("libvpx (fallback from: fake-encoder)",
|
|
fallback_wrapper_.ImplementationName());
|
|
}
|
|
|
|
} // namespace webrtc
|