Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: webrtc/video/video_encoder_unittest.cc

Issue 1328863002: Allow encoders to fall back dynamically to software. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebased Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/video/video_encoder.cc ('k') | webrtc/video_encoder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/video_encoder.h" 11 #include "webrtc/video_encoder.h"
12 12
13 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "webrtc/modules/video_coding/codecs/interface/video_error_codes.h" 14 #include "webrtc/modules/video_coding/codecs/interface/video_error_codes.h"
15 15
16 namespace webrtc { 16 namespace webrtc {
17 17
18 const int kWidth = 320;
19 const int kHeight = 240;
18 const size_t kMaxPayloadSize = 800; 20 const size_t kMaxPayloadSize = 800;
19 21
20 class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test { 22 class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
21 protected: 23 protected:
22 VideoEncoderSoftwareFallbackWrapperTest() 24 VideoEncoderSoftwareFallbackWrapperTest()
23 : fallback_wrapper_(kVideoCodecVP8, &fake_encoder_) {} 25 : fallback_wrapper_(kVideoCodecVP8, &fake_encoder_) {}
24 26
25 class CountingFakeEncoder : public VideoEncoder { 27 class CountingFakeEncoder : public VideoEncoder {
26 public: 28 public:
27 int32_t InitEncode(const VideoCodec* codec_settings, 29 int32_t InitEncode(const VideoCodec* codec_settings,
28 int32_t number_of_cores, 30 int32_t number_of_cores,
29 size_t max_payload_size) override { 31 size_t max_payload_size) override {
30 ++init_encode_count_; 32 ++init_encode_count_;
31 return init_encode_return_code_; 33 return init_encode_return_code_;
32 } 34 }
33 int32_t Encode(const VideoFrame& frame, 35 int32_t Encode(const VideoFrame& frame,
34 const CodecSpecificInfo* codec_specific_info, 36 const CodecSpecificInfo* codec_specific_info,
35 const std::vector<FrameType>* frame_types) override { 37 const std::vector<FrameType>* frame_types) override {
36 ++encode_count_; 38 ++encode_count_;
37 return WEBRTC_VIDEO_CODEC_OK; 39 return encode_return_code_;
38 } 40 }
39 41
40 int32_t RegisterEncodeCompleteCallback( 42 int32_t RegisterEncodeCompleteCallback(
41 EncodedImageCallback* callback) override { 43 EncodedImageCallback* callback) override {
42 encode_complete_callback_ = callback; 44 encode_complete_callback_ = callback;
43 return WEBRTC_VIDEO_CODEC_OK; 45 return WEBRTC_VIDEO_CODEC_OK;
44 } 46 }
45 47
46 int32_t Release() override { 48 int32_t Release() override {
47 ++release_count_; 49 ++release_count_;
(...skipping 12 matching lines...) Expand all
60 62
61 void OnDroppedFrame() override { ++on_dropped_frame_count_; } 63 void OnDroppedFrame() override { ++on_dropped_frame_count_; }
62 64
63 bool SupportsNativeHandle() const override { 65 bool SupportsNativeHandle() const override {
64 ++supports_native_handle_count_; 66 ++supports_native_handle_count_;
65 return false; 67 return false;
66 } 68 }
67 69
68 int init_encode_count_ = 0; 70 int init_encode_count_ = 0;
69 int32_t init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK; 71 int32_t init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
72 int32_t encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
70 int encode_count_ = 0; 73 int encode_count_ = 0;
71 EncodedImageCallback* encode_complete_callback_ = nullptr; 74 EncodedImageCallback* encode_complete_callback_ = nullptr;
72 int release_count_ = 0; 75 int release_count_ = 0;
73 int set_channel_parameters_count_ = 0; 76 int set_channel_parameters_count_ = 0;
74 int set_rates_count_ = 0; 77 int set_rates_count_ = 0;
75 int on_dropped_frame_count_ = 0; 78 int on_dropped_frame_count_ = 0;
76 mutable int supports_native_handle_count_ = 0; 79 mutable int supports_native_handle_count_ = 0;
77 }; 80 };
78 81
79 class FakeEncodedImageCallback : public EncodedImageCallback { 82 class FakeEncodedImageCallback : public EncodedImageCallback {
80 public: 83 public:
81 int32_t Encoded(const EncodedImage& encoded_image, 84 int32_t Encoded(const EncodedImage& encoded_image,
82 const CodecSpecificInfo* codec_specific_info, 85 const CodecSpecificInfo* codec_specific_info,
83 const RTPFragmentationHeader* fragmentation) override { 86 const RTPFragmentationHeader* fragmentation) override {
84 return ++callback_count_; 87 return ++callback_count_;
85 } 88 }
86 int callback_count_ = 0; 89 int callback_count_ = 0;
87 }; 90 };
88 91
89 void UtilizeFallbackEncoder(); 92 void UtilizeFallbackEncoder();
93 void FallbackFromEncodeRequest();
94 void EncodeFrame();
90 95
91 FakeEncodedImageCallback callback_; 96 FakeEncodedImageCallback callback_;
92 CountingFakeEncoder fake_encoder_; 97 CountingFakeEncoder fake_encoder_;
93 VideoEncoderSoftwareFallbackWrapper fallback_wrapper_; 98 VideoEncoderSoftwareFallbackWrapper fallback_wrapper_;
94 VideoCodec codec_ = {}; 99 VideoCodec codec_ = {};
95 VideoFrame frame_; 100 VideoFrame frame_;
96 }; 101 };
97 102
103 void VideoEncoderSoftwareFallbackWrapperTest::EncodeFrame() {
104 frame_.CreateEmptyFrame(kWidth, kHeight, kWidth, (kWidth + 1) / 2,
105 (kWidth + 1) / 2);
106 memset(frame_.buffer(webrtc::kYPlane), 16,
107 frame_.allocated_size(webrtc::kYPlane));
108 memset(frame_.buffer(webrtc::kUPlane), 128,
109 frame_.allocated_size(webrtc::kUPlane));
110 memset(frame_.buffer(webrtc::kVPlane), 128,
111 frame_.allocated_size(webrtc::kVPlane));
112
113 std::vector<FrameType> types(1, kKeyFrame);
114 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
115 fallback_wrapper_.Encode(frame_, nullptr, &types));
116 }
117
98 void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() { 118 void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() {
99 static const int kWidth = 320;
100 static const int kHeight = 240;
101 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); 119 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_);
102 EXPECT_EQ(&callback_, fake_encoder_.encode_complete_callback_); 120 EXPECT_EQ(&callback_, fake_encoder_.encode_complete_callback_);
103 121
104 // Register with failing fake encoder. Should succeed with VP8 fallback. 122 // Register with failing fake encoder. Should succeed with VP8 fallback.
105 codec_.codecType = kVideoCodecVP8; 123 codec_.codecType = kVideoCodecVP8;
106 codec_.maxFramerate = 30; 124 codec_.maxFramerate = 30;
107 codec_.width = kWidth; 125 codec_.width = kWidth;
108 codec_.height = kHeight; 126 codec_.height = kHeight;
109 fake_encoder_.init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR; 127 fake_encoder_.init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
110 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, 128 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
111 fallback_wrapper_.InitEncode(&codec_, 2, kMaxPayloadSize)); 129 fallback_wrapper_.InitEncode(&codec_, 2, kMaxPayloadSize));
112 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.SetRates(300, 30)); 130 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.SetRates(300, 30));
113 131
114 frame_.CreateEmptyFrame(kWidth, kHeight, kWidth, (kWidth + 1) / 2, 132 int callback_count = callback_.callback_count_;
115 (kWidth + 1) / 2); 133 int encode_count = fake_encoder_.encode_count_;
116 memset(frame_.buffer(webrtc::kYPlane), 16, 134 EncodeFrame();
117 frame_.allocated_size(webrtc::kYPlane)); 135 EXPECT_EQ(encode_count, fake_encoder_.encode_count_);
118 memset(frame_.buffer(webrtc::kUPlane), 128, 136 EXPECT_EQ(callback_count + 1, callback_.callback_count_);
119 frame_.allocated_size(webrtc::kUPlane)); 137 }
120 memset(frame_.buffer(webrtc::kVPlane), 128,
121 frame_.allocated_size(webrtc::kVPlane));
122 138
123 std::vector<FrameType> types(1, kKeyFrame); 139 void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() {
124 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, 140 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_);
125 fallback_wrapper_.Encode(frame_, nullptr, &types)); 141 codec_.codecType = kVideoCodecVP8;
126 EXPECT_EQ(0, fake_encoder_.encode_count_); 142 codec_.maxFramerate = 30;
127 EXPECT_GT(callback_.callback_count_, 0); 143 codec_.width = kWidth;
144 codec_.height = kHeight;
145 fallback_wrapper_.InitEncode(&codec_, 2, kMaxPayloadSize);
146 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.SetRates(300, 30));
147 EXPECT_EQ(1, fake_encoder_.init_encode_count_);
148
149 // Have the non-fallback encoder request a software fallback.
150 fake_encoder_.encode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
151 int callback_count = callback_.callback_count_;
152 int encode_count = fake_encoder_.encode_count_;
153 EncodeFrame();
154 // Single encode request, which returned failure.
155 EXPECT_EQ(encode_count + 1, fake_encoder_.encode_count_);
156 EXPECT_EQ(callback_count + 1, callback_.callback_count_);
128 } 157 }
129 158
130 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, InitializesEncoder) { 159 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, InitializesEncoder) {
131 VideoCodec codec = {}; 160 VideoCodec codec = {};
132 fallback_wrapper_.InitEncode(&codec, 2, kMaxPayloadSize); 161 fallback_wrapper_.InitEncode(&codec, 2, kMaxPayloadSize);
133 EXPECT_EQ(1, fake_encoder_.init_encode_count_); 162 EXPECT_EQ(1, fake_encoder_.init_encode_count_);
134 } 163 }
135 164
165 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, EncodeRequestsFallback) {
166 FallbackFromEncodeRequest();
167 // After fallback, further encodes shouldn't hit the fake encoder.
168 int encode_count = fake_encoder_.encode_count_;
169 EncodeFrame();
170 EXPECT_EQ(encode_count, fake_encoder_.encode_count_);
171 }
172
136 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, CanUtilizeFallbackEncoder) { 173 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, CanUtilizeFallbackEncoder) {
137 UtilizeFallbackEncoder(); 174 UtilizeFallbackEncoder();
138 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); 175 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
139 } 176 }
140 177
141 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, 178 TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
142 InternalEncoderNotReleasedDuringFallback) { 179 InternalEncoderReleasedDuringFallback) {
180 EXPECT_EQ(0, fake_encoder_.release_count_);
143 UtilizeFallbackEncoder(); 181 UtilizeFallbackEncoder();
182 EXPECT_EQ(1, fake_encoder_.release_count_);
144 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); 183 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
145 EXPECT_EQ(0, fake_encoder_.release_count_); 184 // No extra release when the fallback is released.
185 EXPECT_EQ(1, fake_encoder_.release_count_);
146 } 186 }
147 187
148 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, 188 TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
149 InternalEncoderNotEncodingDuringFallback) { 189 InternalEncoderNotEncodingDuringFallback) {
150 UtilizeFallbackEncoder(); 190 UtilizeFallbackEncoder();
151 EXPECT_EQ(0, fake_encoder_.encode_count_); 191 int encode_count = fake_encoder_.encode_count_;
192 EncodeFrame();
193 EXPECT_EQ(encode_count, fake_encoder_.encode_count_);
152 194
153 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); 195 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
154 } 196 }
155 197
156 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, 198 TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
157 CanRegisterCallbackWhileUsingFallbackEncoder) { 199 CanRegisterCallbackWhileUsingFallbackEncoder) {
158 UtilizeFallbackEncoder(); 200 UtilizeFallbackEncoder();
159 // Registering an encode-complete callback should still work when fallback 201 // Registering an encode-complete callback should still work when fallback
160 // encoder is being used. 202 // encoder is being used.
161 FakeEncodedImageCallback callback2; 203 FakeEncodedImageCallback callback2;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 253
212 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, 254 TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
213 SupportsNativeHandleNotForwardedDuringFallback) { 255 SupportsNativeHandleNotForwardedDuringFallback) {
214 UtilizeFallbackEncoder(); 256 UtilizeFallbackEncoder();
215 fallback_wrapper_.SupportsNativeHandle(); 257 fallback_wrapper_.SupportsNativeHandle();
216 EXPECT_EQ(0, fake_encoder_.supports_native_handle_count_); 258 EXPECT_EQ(0, fake_encoder_.supports_native_handle_count_);
217 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); 259 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
218 } 260 }
219 261
220 } // namespace webrtc 262 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/video/video_encoder.cc ('k') | webrtc/video_encoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698