OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |