Chromium Code Reviews| 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<VideoFrameType>* frame_types) override { | 37 const std::vector<VideoFrameType>* 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<VideoFrameType> 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 EncodeFrame(); |
| 115 (kWidth + 1) / 2); | 133 EXPECT_EQ(0, fake_encoder_.encode_count_); |
| 116 memset(frame_.buffer(webrtc::kYPlane), 16, | 134 EXPECT_GT(callback_.callback_count_, 0); |
|
pbos-webrtc
2015/10/20 09:06:56
Not EQ(1, ...) ? or can you fetch it before and ex
noahric
2015/10/20 21:46:42
Done (prev_count + 1). Also updated the encode_cou
| |
| 117 frame_.allocated_size(webrtc::kYPlane)); | 135 } |
| 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 | 136 |
| 123 std::vector<VideoFrameType> types(1, kKeyFrame); | 137 void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() { |
| 124 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 138 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); |
| 125 fallback_wrapper_.Encode(frame_, nullptr, &types)); | 139 codec_.codecType = kVideoCodecVP8; |
| 126 EXPECT_EQ(0, fake_encoder_.encode_count_); | 140 codec_.maxFramerate = 30; |
| 141 codec_.width = kWidth; | |
| 142 codec_.height = kHeight; | |
| 143 fallback_wrapper_.InitEncode(&codec_, 2, kMaxPayloadSize); | |
| 144 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.SetRates(300, 30)); | |
| 145 EXPECT_EQ(1, fake_encoder_.init_encode_count_); | |
| 146 | |
| 147 // Have the non-fallback encoder request a software fallback. | |
| 148 fake_encoder_.encode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; | |
| 149 EncodeFrame(); | |
| 150 // Single encode request, which returned failure. | |
| 151 EXPECT_EQ(1, fake_encoder_.encode_count_); | |
| 127 EXPECT_GT(callback_.callback_count_, 0); | 152 EXPECT_GT(callback_.callback_count_, 0); |
|
pbos-webrtc
2015/10/20 09:06:56
EQ(1, callback_.callback_count_) or prev_count + 1
noahric
2015/10/20 21:46:42
Done (prev_count + 1 for both).
| |
| 128 } | 153 } |
| 129 | 154 |
| 130 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, InitializesEncoder) { | 155 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, InitializesEncoder) { |
| 131 VideoCodec codec = {}; | 156 VideoCodec codec = {}; |
| 132 fallback_wrapper_.InitEncode(&codec, 2, kMaxPayloadSize); | 157 fallback_wrapper_.InitEncode(&codec, 2, kMaxPayloadSize); |
| 133 EXPECT_EQ(1, fake_encoder_.init_encode_count_); | 158 EXPECT_EQ(1, fake_encoder_.init_encode_count_); |
| 134 } | 159 } |
| 135 | 160 |
| 161 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, EncodeRequestsFallback) { | |
| 162 FallbackFromEncodeRequest(); | |
| 163 // After fallback, further encodes shouldn't hit the fake encoder. | |
| 164 int encode_count = fake_encoder_.encode_count_; | |
| 165 EncodeFrame(); | |
| 166 EXPECT_EQ(encode_count, fake_encoder_.encode_count_); | |
| 167 } | |
| 168 | |
| 136 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, CanUtilizeFallbackEncoder) { | 169 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, CanUtilizeFallbackEncoder) { |
| 137 UtilizeFallbackEncoder(); | 170 UtilizeFallbackEncoder(); |
| 138 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); | 171 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); |
| 139 } | 172 } |
| 140 | 173 |
| 141 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, | 174 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, |
| 142 InternalEncoderNotReleasedDuringFallback) { | 175 InternalEncoderReleasedDuringFallback) { |
| 143 UtilizeFallbackEncoder(); | 176 UtilizeFallbackEncoder(); |
| 144 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); | 177 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); |
| 145 EXPECT_EQ(0, fake_encoder_.release_count_); | 178 EXPECT_EQ(1, fake_encoder_.release_count_); |
| 146 } | 179 } |
| 147 | 180 |
| 148 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, | 181 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, |
| 149 InternalEncoderNotEncodingDuringFallback) { | 182 InternalEncoderNotEncodingDuringFallback) { |
| 150 UtilizeFallbackEncoder(); | 183 UtilizeFallbackEncoder(); |
| 151 EXPECT_EQ(0, fake_encoder_.encode_count_); | 184 int encode_count = fake_encoder_.encode_count_; |
| 185 EncodeFrame(); | |
| 186 EXPECT_EQ(encode_count, fake_encoder_.encode_count_); | |
| 152 | 187 |
| 153 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); | 188 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); |
| 154 } | 189 } |
| 155 | 190 |
| 156 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, | 191 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, |
| 157 CanRegisterCallbackWhileUsingFallbackEncoder) { | 192 CanRegisterCallbackWhileUsingFallbackEncoder) { |
| 158 UtilizeFallbackEncoder(); | 193 UtilizeFallbackEncoder(); |
| 159 // Registering an encode-complete callback should still work when fallback | 194 // Registering an encode-complete callback should still work when fallback |
| 160 // encoder is being used. | 195 // encoder is being used. |
| 161 FakeEncodedImageCallback callback2; | 196 FakeEncodedImageCallback callback2; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 | 246 |
| 212 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, | 247 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, |
| 213 SupportsNativeHandleNotForwardedDuringFallback) { | 248 SupportsNativeHandleNotForwardedDuringFallback) { |
| 214 UtilizeFallbackEncoder(); | 249 UtilizeFallbackEncoder(); |
| 215 fallback_wrapper_.SupportsNativeHandle(); | 250 fallback_wrapper_.SupportsNativeHandle(); |
| 216 EXPECT_EQ(0, fake_encoder_.supports_native_handle_count_); | 251 EXPECT_EQ(0, fake_encoder_.supports_native_handle_count_); |
| 217 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); | 252 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); |
| 218 } | 253 } |
| 219 | 254 |
| 220 } // namespace webrtc | 255 } // namespace webrtc |
| OLD | NEW |