blob: be0170cdbeb3cbb5c3cfe99ff981ba7e304ab462 [file] [log] [blame]
Peter Boström4d71ede2015-05-19 23:09:35 +02001/*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/video_encoder.h"
12
13#include "testing/gtest/include/gtest/gtest.h"
14#include "webrtc/modules/video_coding/codecs/interface/video_error_codes.h"
15
16namespace webrtc {
17
18const size_t kMaxPayloadSize = 800;
19
20class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
21 protected:
22 VideoEncoderSoftwareFallbackWrapperTest()
23 : fallback_wrapper_(kVideoCodecVP8, &fake_encoder_) {}
24
25 class CountingFakeEncoder : public VideoEncoder {
26 public:
27 int32_t InitEncode(const VideoCodec* codec_settings,
28 int32_t number_of_cores,
29 size_t max_payload_size) override {
30 ++init_encode_count_;
31 return init_encode_return_code_;
32 }
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070033 int32_t Encode(const VideoFrame& frame,
Peter Boström4d71ede2015-05-19 23:09:35 +020034 const CodecSpecificInfo* codec_specific_info,
35 const std::vector<VideoFrameType>* frame_types) override {
36 ++encode_count_;
37 return WEBRTC_VIDEO_CODEC_OK;
38 }
39
40 int32_t RegisterEncodeCompleteCallback(
41 EncodedImageCallback* callback) override {
42 encode_complete_callback_ = callback;
43 return WEBRTC_VIDEO_CODEC_OK;
44 }
45
46 int32_t Release() override {
47 ++release_count_;
48 return WEBRTC_VIDEO_CODEC_OK;
49 }
50
51 int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) override {
52 ++set_channel_parameters_count_;
53 return WEBRTC_VIDEO_CODEC_OK;
54 }
55
56 int32_t SetRates(uint32_t bitrate, uint32_t framerate) override {
57 ++set_rates_count_;
58 return WEBRTC_VIDEO_CODEC_OK;
59 }
60
61 void OnDroppedFrame() override { ++on_dropped_frame_count_; }
62
Peter Boströmeb66e802015-06-05 11:08:03 +020063 bool SupportsNativeHandle() const override {
64 ++supports_native_handle_count_;
65 return false;
66 }
67
Peter Boström4d71ede2015-05-19 23:09:35 +020068 int init_encode_count_ = 0;
69 int32_t init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
70 int encode_count_ = 0;
71 EncodedImageCallback* encode_complete_callback_ = nullptr;
72 int release_count_ = 0;
73 int set_channel_parameters_count_ = 0;
74 int set_rates_count_ = 0;
75 int on_dropped_frame_count_ = 0;
Peter Boströmeb66e802015-06-05 11:08:03 +020076 mutable int supports_native_handle_count_ = 0;
Peter Boström4d71ede2015-05-19 23:09:35 +020077 };
78
79 class FakeEncodedImageCallback : public EncodedImageCallback {
80 public:
81 int32_t Encoded(const EncodedImage& encoded_image,
82 const CodecSpecificInfo* codec_specific_info,
83 const RTPFragmentationHeader* fragmentation) override {
84 return ++callback_count_;
85 }
86 int callback_count_ = 0;
87 };
88
89 void UtilizeFallbackEncoder();
90
91 FakeEncodedImageCallback callback_;
92 CountingFakeEncoder fake_encoder_;
93 VideoEncoderSoftwareFallbackWrapper fallback_wrapper_;
94 VideoCodec codec_ = {};
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070095 VideoFrame frame_;
Peter Boström4d71ede2015-05-19 23:09:35 +020096};
97
98void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() {
99 static const int kWidth = 320;
100 static const int kHeight = 240;
101 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_);
102 EXPECT_EQ(&callback_, fake_encoder_.encode_complete_callback_);
103
104 // Register with failing fake encoder. Should succeed with VP8 fallback.
105 codec_.codecType = kVideoCodecVP8;
106 codec_.maxFramerate = 30;
107 codec_.width = kWidth;
108 codec_.height = kHeight;
109 fake_encoder_.init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
110 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
111 fallback_wrapper_.InitEncode(&codec_, 2, kMaxPayloadSize));
112 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.SetRates(300, 30));
113
114 frame_.CreateEmptyFrame(kWidth, kHeight, kWidth, (kWidth + 1) / 2,
115 (kWidth + 1) / 2);
116 memset(frame_.buffer(webrtc::kYPlane), 16,
117 frame_.allocated_size(webrtc::kYPlane));
118 memset(frame_.buffer(webrtc::kUPlane), 128,
119 frame_.allocated_size(webrtc::kUPlane));
120 memset(frame_.buffer(webrtc::kVPlane), 128,
121 frame_.allocated_size(webrtc::kVPlane));
122
123 std::vector<VideoFrameType> types(1, kKeyFrame);
124 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
125 fallback_wrapper_.Encode(frame_, nullptr, &types));
126 EXPECT_EQ(0, fake_encoder_.encode_count_);
127 EXPECT_GT(callback_.callback_count_, 0);
128}
129
130TEST_F(VideoEncoderSoftwareFallbackWrapperTest, InitializesEncoder) {
131 VideoCodec codec = {};
132 fallback_wrapper_.InitEncode(&codec, 2, kMaxPayloadSize);
133 EXPECT_EQ(1, fake_encoder_.init_encode_count_);
134}
135
136TEST_F(VideoEncoderSoftwareFallbackWrapperTest, CanUtilizeFallbackEncoder) {
137 UtilizeFallbackEncoder();
138 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
139}
140
141TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
142 InternalEncoderNotReleasedDuringFallback) {
143 UtilizeFallbackEncoder();
144 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
145 EXPECT_EQ(0, fake_encoder_.release_count_);
146}
147
148TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
149 InternalEncoderNotEncodingDuringFallback) {
150 UtilizeFallbackEncoder();
151 EXPECT_EQ(0, fake_encoder_.encode_count_);
152
153 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
154}
155
156TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
157 CanRegisterCallbackWhileUsingFallbackEncoder) {
158 UtilizeFallbackEncoder();
159 // Registering an encode-complete callback should still work when fallback
160 // encoder is being used.
161 FakeEncodedImageCallback callback2;
162 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback2);
163 EXPECT_EQ(&callback2, fake_encoder_.encode_complete_callback_);
164
165 // Encoding a frame using the fallback should arrive at the new callback.
166 std::vector<VideoFrameType> types(1, kKeyFrame);
167 frame_.set_timestamp(frame_.timestamp() + 1000);
168 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
169 fallback_wrapper_.Encode(frame_, nullptr, &types));
170
171 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
172}
173
174TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
175 SetChannelParametersForwardedDuringFallback) {
176 UtilizeFallbackEncoder();
177 EXPECT_EQ(0, fake_encoder_.set_channel_parameters_count_);
178 fallback_wrapper_.SetChannelParameters(1, 1);
179 EXPECT_EQ(1, fake_encoder_.set_channel_parameters_count_);
180 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
181}
182
183TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
184 SetRatesForwardedDuringFallback) {
185 UtilizeFallbackEncoder();
186 EXPECT_EQ(1, fake_encoder_.set_rates_count_);
187 fallback_wrapper_.SetRates(1, 1);
188 EXPECT_EQ(2, fake_encoder_.set_rates_count_);
189 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
190}
191
192TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
193 OnDroppedFrameForwardedWithoutFallback) {
194 fallback_wrapper_.OnDroppedFrame();
195 EXPECT_EQ(1, fake_encoder_.on_dropped_frame_count_);
196}
197
198TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
199 OnDroppedFrameNotForwardedDuringFallback) {
200 UtilizeFallbackEncoder();
201 fallback_wrapper_.OnDroppedFrame();
202 EXPECT_EQ(0, fake_encoder_.on_dropped_frame_count_);
203 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
204}
205
Peter Boströmeb66e802015-06-05 11:08:03 +0200206TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
207 SupportsNativeHandleForwardedWithoutFallback) {
208 fallback_wrapper_.SupportsNativeHandle();
209 EXPECT_EQ(1, fake_encoder_.supports_native_handle_count_);
210}
211
212TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
213 SupportsNativeHandleNotForwardedDuringFallback) {
214 UtilizeFallbackEncoder();
215 fallback_wrapper_.SupportsNativeHandle();
216 EXPECT_EQ(0, fake_encoder_.supports_native_handle_count_);
217 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
218}
219
Peter Boström4d71ede2015-05-19 23:09:35 +0200220} // namespace webrtc