Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 #include "webrtc/rtc_base/timeutils.h" | 22 #include "webrtc/rtc_base/timeutils.h" |
| 23 #include "webrtc/test/field_trial.h" | 23 #include "webrtc/test/field_trial.h" |
| 24 #include "webrtc/test/frame_utils.h" | 24 #include "webrtc/test/frame_utils.h" |
| 25 #include "webrtc/test/gtest.h" | 25 #include "webrtc/test/gtest.h" |
| 26 #include "webrtc/test/testsupport/fileutils.h" | 26 #include "webrtc/test/testsupport/fileutils.h" |
| 27 #include "webrtc/test/video_codec_settings.h" | 27 #include "webrtc/test/video_codec_settings.h" |
| 28 | 28 |
| 29 namespace webrtc { | 29 namespace webrtc { |
| 30 | 30 |
| 31 namespace { | 31 namespace { |
| 32 | |
| 33 void Calc16ByteAlignedStride(int width, int* stride_y, int* stride_uv) { | |
| 34 *stride_y = 16 * ((width + 15) / 16); | |
| 35 *stride_uv = 16 * ((width + 31) / 32); | |
| 36 } | |
| 37 | |
| 38 constexpr int64_t kMaxWaitEncTimeMs = 100; | 32 constexpr int64_t kMaxWaitEncTimeMs = 100; |
| 39 constexpr int64_t kMaxWaitDecTimeMs = 25; | 33 constexpr int64_t kMaxWaitDecTimeMs = 25; |
| 40 constexpr uint32_t kTestTimestamp = 123; | 34 constexpr uint32_t kTestTimestamp = 123; |
| 41 constexpr int64_t kTestNtpTimeMs = 456; | 35 constexpr int64_t kTestNtpTimeMs = 456; |
| 42 constexpr uint32_t kTimestampIncrementPerFrame = 3000; | 36 constexpr uint32_t kTimestampIncrementPerFrame = 3000; |
| 43 constexpr int kNumCores = 1; | 37 constexpr int kNumCores = 1; |
| 44 constexpr size_t kMaxPayloadSize = 1440; | 38 constexpr size_t kMaxPayloadSize = 1440; |
| 45 constexpr int kMinPixelsPerFrame = 12345; | 39 constexpr int kMinPixelsPerFrame = 12345; |
| 46 constexpr int kDefaultMinPixelsPerFrame = 320 * 180; | 40 constexpr int kDefaultMinPixelsPerFrame = 320 * 180; |
| 47 constexpr int kWidth = 172; | 41 constexpr int kWidth = 172; |
| 48 constexpr int kHeight = 144; | 42 constexpr int kHeight = 144; |
| 43 | |
| 44 void Calc16ByteAlignedStride(int width, int* stride_y, int* stride_uv) { | |
| 45 *stride_y = 16 * ((width + 15) / 16); | |
| 46 *stride_uv = 16 * ((width + 31) / 32); | |
| 47 } | |
| 49 } // namespace | 48 } // namespace |
| 50 | 49 |
| 51 class Vp8UnitTestEncodeCompleteCallback : public webrtc::EncodedImageCallback { | 50 class EncodedImageCallbackTestImpl : public webrtc::EncodedImageCallback { |
| 52 public: | 51 public: |
| 53 Vp8UnitTestEncodeCompleteCallback(EncodedImage* frame, | |
| 54 CodecSpecificInfo* codec_specific_info) | |
| 55 : encoded_frame_(frame), | |
| 56 codec_specific_info_(codec_specific_info), | |
| 57 encode_complete_(false) {} | |
| 58 | |
| 59 Result OnEncodedImage(const EncodedImage& encoded_frame, | 52 Result OnEncodedImage(const EncodedImage& encoded_frame, |
| 60 const CodecSpecificInfo* codec_specific_info, | 53 const CodecSpecificInfo* codec_specific_info, |
| 61 const RTPFragmentationHeader* fragmentation) override; | 54 const RTPFragmentationHeader* fragmentation) override { |
| 62 bool EncodeComplete(); | 55 EXPECT_GT(encoded_frame._length, 0u); |
| 56 VerifyQpParser(encoded_frame); | |
| 57 | |
| 58 if (encoded_frame_._size != encoded_frame._size) { | |
| 59 delete[] encoded_frame_._buffer; | |
| 60 frame_buffer_.reset(new uint8_t[encoded_frame._size]); | |
| 61 } | |
| 62 memcpy(frame_buffer_.get(), encoded_frame._buffer, encoded_frame._length); | |
|
brandtr
2017/08/22 10:38:05
RTC_DCHECK(frame_buffer_) ?
åsapersson
2017/08/22 11:03:55
Done.
| |
| 63 encoded_frame_ = encoded_frame; | |
| 64 encoded_frame_._buffer = frame_buffer_.get(); | |
| 65 | |
| 66 // Skip |codec_name|, to avoid allocating. | |
| 67 EXPECT_STREQ("libvpx", codec_specific_info->codec_name); | |
| 68 EXPECT_EQ(kVideoCodecVP8, codec_specific_info->codecType); | |
| 69 codec_specific_info_.codecType = codec_specific_info->codecType; | |
| 70 codec_specific_info_.codecSpecific = codec_specific_info->codecSpecific; | |
| 71 complete_ = true; | |
| 72 return Result(Result::OK, 0); | |
| 73 } | |
| 63 | 74 |
| 64 void VerifyQpParser(const EncodedImage& encoded_frame) const { | 75 void VerifyQpParser(const EncodedImage& encoded_frame) const { |
| 65 int qp; | 76 int qp; |
| 66 ASSERT_TRUE(vp8::GetQp(encoded_frame._buffer, encoded_frame._length, &qp)); | 77 ASSERT_TRUE(vp8::GetQp(encoded_frame._buffer, encoded_frame._length, &qp)); |
| 67 EXPECT_EQ(encoded_frame.qp_, qp) << "Encoder QP != parsed bitstream QP."; | 78 EXPECT_EQ(encoded_frame.qp_, qp) << "Encoder QP != parsed bitstream QP."; |
| 68 } | 79 } |
| 69 | 80 |
| 70 private: | 81 bool EncodeComplete() { |
| 71 EncodedImage* const encoded_frame_; | 82 if (complete_) { |
| 72 CodecSpecificInfo* const codec_specific_info_; | 83 complete_ = false; |
| 84 return true; | |
| 85 } | |
| 86 return false; | |
| 87 } | |
| 88 | |
| 89 EncodedImage encoded_frame_; | |
| 90 CodecSpecificInfo codec_specific_info_; | |
| 73 std::unique_ptr<uint8_t[]> frame_buffer_; | 91 std::unique_ptr<uint8_t[]> frame_buffer_; |
| 74 bool encode_complete_; | 92 bool complete_ = false; |
| 75 }; | 93 }; |
| 76 | 94 |
| 77 webrtc::EncodedImageCallback::Result | 95 class DecodedImageCallbackTestImpl : public webrtc::DecodedImageCallback { |
| 78 Vp8UnitTestEncodeCompleteCallback::OnEncodedImage( | |
| 79 const EncodedImage& encoded_frame, | |
| 80 const CodecSpecificInfo* codec_specific_info, | |
| 81 const RTPFragmentationHeader* fragmentation) { | |
| 82 EXPECT_GT(encoded_frame._length, 0u); | |
| 83 VerifyQpParser(encoded_frame); | |
| 84 | |
| 85 if (encoded_frame_->_size != encoded_frame._size) { | |
| 86 delete[] encoded_frame_->_buffer; | |
| 87 frame_buffer_.reset(new uint8_t[encoded_frame._size]); | |
| 88 } | |
| 89 memcpy(frame_buffer_.get(), encoded_frame._buffer, encoded_frame._length); | |
| 90 *encoded_frame_ = encoded_frame; | |
| 91 encoded_frame_->_buffer = frame_buffer_.get(); | |
| 92 | |
| 93 // Skip |codec_name|, to avoid allocating. | |
| 94 codec_specific_info_->codecType = codec_specific_info->codecType; | |
| 95 codec_specific_info_->codecSpecific = codec_specific_info->codecSpecific; | |
| 96 encode_complete_ = true; | |
| 97 return Result(Result::OK, 0); | |
| 98 } | |
| 99 | |
| 100 bool Vp8UnitTestEncodeCompleteCallback::EncodeComplete() { | |
| 101 if (encode_complete_) { | |
| 102 encode_complete_ = false; | |
| 103 return true; | |
| 104 } | |
| 105 return false; | |
| 106 } | |
| 107 | |
| 108 class Vp8UnitTestDecodeCompleteCallback : public webrtc::DecodedImageCallback { | |
| 109 public: | 96 public: |
| 110 explicit Vp8UnitTestDecodeCompleteCallback(rtc::Optional<VideoFrame>* frame, | |
| 111 rtc::Optional<uint8_t>* qp) | |
| 112 : decoded_frame_(frame), decoded_qp_(qp), decode_complete_(false) {} | |
| 113 int32_t Decoded(VideoFrame& frame) override { | 97 int32_t Decoded(VideoFrame& frame) override { |
| 114 RTC_NOTREACHED(); | 98 RTC_NOTREACHED(); |
| 115 return -1; | 99 return -1; |
| 116 } | 100 } |
| 117 int32_t Decoded(VideoFrame& frame, int64_t decode_time_ms) override { | 101 int32_t Decoded(VideoFrame& frame, int64_t decode_time_ms) override { |
| 118 RTC_NOTREACHED(); | 102 RTC_NOTREACHED(); |
| 119 return -1; | 103 return -1; |
| 120 } | 104 } |
| 121 void Decoded(VideoFrame& frame, | 105 void Decoded(VideoFrame& frame, |
| 122 rtc::Optional<int32_t> decode_time_ms, | 106 rtc::Optional<int32_t> decode_time_ms, |
| 123 rtc::Optional<uint8_t> qp) override; | 107 rtc::Optional<uint8_t> qp) override { |
| 124 bool DecodeComplete(); | 108 EXPECT_GT(frame.width(), 0); |
| 109 EXPECT_GT(frame.height(), 0); | |
| 110 EXPECT_TRUE(qp); | |
| 111 frame_ = rtc::Optional<VideoFrame>(frame); | |
| 112 qp_ = qp; | |
| 113 complete_ = true; | |
| 114 } | |
| 125 | 115 |
| 126 private: | 116 bool DecodeComplete() { |
| 127 rtc::Optional<VideoFrame>* decoded_frame_; | 117 if (complete_) { |
| 128 rtc::Optional<uint8_t>* decoded_qp_; | 118 complete_ = false; |
| 129 bool decode_complete_; | 119 return true; |
| 120 } | |
| 121 return false; | |
| 122 } | |
| 123 | |
| 124 rtc::Optional<VideoFrame> frame_; | |
| 125 rtc::Optional<uint8_t> qp_; | |
| 126 bool complete_ = false; | |
| 130 }; | 127 }; |
| 131 | 128 |
| 132 bool Vp8UnitTestDecodeCompleteCallback::DecodeComplete() { | |
| 133 if (decode_complete_) { | |
| 134 decode_complete_ = false; | |
| 135 return true; | |
| 136 } | |
| 137 return false; | |
| 138 } | |
| 139 | |
| 140 void Vp8UnitTestDecodeCompleteCallback::Decoded( | |
| 141 VideoFrame& frame, | |
| 142 rtc::Optional<int32_t> decode_time_ms, | |
| 143 rtc::Optional<uint8_t> qp) { | |
| 144 EXPECT_GT(frame.width(), 0); | |
| 145 EXPECT_GT(frame.height(), 0); | |
| 146 *decoded_frame_ = rtc::Optional<VideoFrame>(frame); | |
| 147 *decoded_qp_ = qp; | |
| 148 decode_complete_ = true; | |
| 149 } | |
| 150 | |
| 151 class TestVp8Impl : public ::testing::Test { | 129 class TestVp8Impl : public ::testing::Test { |
| 152 protected: | 130 public: |
| 153 TestVp8Impl() : TestVp8Impl("") {} | 131 TestVp8Impl() : TestVp8Impl("") {} |
| 154 explicit TestVp8Impl(const std::string& field_trials) | 132 explicit TestVp8Impl(const std::string& field_trials) |
| 155 : override_field_trials_(field_trials) {} | 133 : override_field_trials_(field_trials), |
| 134 encoder_(VP8Encoder::Create()), | |
| 135 decoder_(VP8Decoder::Create()) {} | |
| 136 virtual ~TestVp8Impl() {} | |
| 156 | 137 |
| 138 protected: | |
| 157 virtual void SetUp() { | 139 virtual void SetUp() { |
| 158 encoder_.reset(VP8Encoder::Create()); | 140 encoder_->RegisterEncodeCompleteCallback(&encoded_cb_); |
| 159 decoder_.reset(VP8Decoder::Create()); | 141 decoder_->RegisterDecodeCompleteCallback(&decoded_cb_); |
| 160 encode_complete_callback_.reset(new Vp8UnitTestEncodeCompleteCallback( | 142 SetupCodecSettings(); |
| 161 &encoded_frame_, &codec_specific_info_)); | 143 SetupInputFrame(); |
| 162 decode_complete_callback_.reset( | 144 } |
| 163 new Vp8UnitTestDecodeCompleteCallback(&decoded_frame_, &decoded_qp_)); | |
| 164 encoder_->RegisterEncodeCompleteCallback(encode_complete_callback_.get()); | |
| 165 decoder_->RegisterDecodeCompleteCallback(decode_complete_callback_.get()); | |
| 166 | 145 |
| 167 SetupCodecSettings(); | 146 void SetupInputFrame() { |
| 168 | |
| 169 // Using a QCIF image (aligned stride (u,v planes) > width). | 147 // Using a QCIF image (aligned stride (u,v planes) > width). |
| 170 // Processing only one frame. | 148 // Processing only one frame. |
| 171 FILE* file = fopen(test::ResourcePath("paris_qcif", "yuv").c_str(), "rb"); | 149 FILE* file = fopen(test::ResourcePath("paris_qcif", "yuv").c_str(), "rb"); |
| 172 ASSERT_TRUE(file != nullptr); | 150 ASSERT_TRUE(file != nullptr); |
| 173 rtc::scoped_refptr<I420BufferInterface> compact_buffer( | 151 rtc::scoped_refptr<I420BufferInterface> compact_buffer( |
| 174 test::ReadI420Buffer(kWidth, kHeight, file)); | 152 test::ReadI420Buffer(kWidth, kHeight, file)); |
| 175 ASSERT_TRUE(compact_buffer); | 153 ASSERT_TRUE(compact_buffer); |
| 154 | |
| 176 // Setting aligned stride values. | 155 // Setting aligned stride values. |
| 177 int stride_uv; | 156 int stride_uv; |
| 178 int stride_y; | 157 int stride_y; |
| 179 Calc16ByteAlignedStride(kWidth, &stride_y, &stride_uv); | 158 Calc16ByteAlignedStride(kWidth, &stride_y, &stride_uv); |
| 180 EXPECT_EQ(stride_y, 176); | 159 EXPECT_EQ(stride_y, 176); |
| 181 EXPECT_EQ(stride_uv, 96); | 160 EXPECT_EQ(stride_uv, 96); |
| 182 | |
| 183 rtc::scoped_refptr<I420Buffer> stride_buffer( | 161 rtc::scoped_refptr<I420Buffer> stride_buffer( |
| 184 I420Buffer::Create(kWidth, kHeight, stride_y, stride_uv, stride_uv)); | 162 I420Buffer::Create(kWidth, kHeight, stride_y, stride_uv, stride_uv)); |
| 185 | 163 |
| 186 // No scaling in our case, just a copy, to add stride to the image. | 164 // No scaling in our case, just a copy, to add stride to the image. |
| 187 stride_buffer->ScaleFrom(*compact_buffer); | 165 stride_buffer->ScaleFrom(*compact_buffer); |
| 188 | 166 |
| 189 input_frame_.reset(new VideoFrame(stride_buffer, kVideoRotation_0, 0)); | 167 input_frame_.reset(new VideoFrame(stride_buffer, kVideoRotation_0, 0)); |
| 190 input_frame_->set_timestamp(kTestTimestamp); | 168 input_frame_->set_timestamp(kTestTimestamp); |
| 191 fclose(file); | 169 fclose(file); |
| 192 } | 170 } |
| 193 | 171 |
| 194 void SetupCodecSettings() { | 172 void SetupCodecSettings() { |
| 195 webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings_); | 173 webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings_); |
| 196 codec_settings_.maxBitrate = 4000; | 174 codec_settings_.maxBitrate = 4000; |
| 197 codec_settings_.width = kWidth; | 175 codec_settings_.width = kWidth; |
| 198 codec_settings_.height = kHeight; | 176 codec_settings_.height = kHeight; |
| 199 codec_settings_.VP8()->denoisingOn = true; | 177 codec_settings_.VP8()->denoisingOn = true; |
| 200 codec_settings_.VP8()->frameDroppingOn = false; | 178 codec_settings_.VP8()->frameDroppingOn = false; |
| 201 codec_settings_.VP8()->automaticResizeOn = false; | 179 codec_settings_.VP8()->automaticResizeOn = false; |
| 202 codec_settings_.VP8()->complexity = kComplexityNormal; | 180 codec_settings_.VP8()->complexity = kComplexityNormal; |
| 203 codec_settings_.VP8()->tl_factory = &tl_factory_; | 181 codec_settings_.VP8()->tl_factory = &tl_factory_; |
| 204 } | 182 } |
| 205 | 183 |
| 206 void SetUpEncodeDecode() { | 184 void InitEncodeDecode() { |
| 207 EXPECT_EQ( | 185 EXPECT_EQ( |
| 208 WEBRTC_VIDEO_CODEC_OK, | 186 WEBRTC_VIDEO_CODEC_OK, |
| 209 encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); | 187 encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); |
| 210 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 188 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 211 decoder_->InitDecode(&codec_settings_, kNumCores)); | 189 decoder_->InitDecode(&codec_settings_, kNumCores)); |
| 212 } | 190 } |
| 213 | 191 |
| 214 void WaitForEncodedFrame() const { | 192 void WaitForEncodedFrame() { |
| 215 int64_t start_ms = rtc::TimeMillis(); | 193 int64_t start_ms = rtc::TimeMillis(); |
| 216 while (rtc::TimeMillis() - start_ms < kMaxWaitEncTimeMs) { | 194 while (rtc::TimeMillis() - start_ms < kMaxWaitEncTimeMs) { |
| 217 if (encode_complete_callback_->EncodeComplete()) { | 195 if (encoded_cb_.EncodeComplete()) |
| 218 return; | 196 return; |
| 219 } | |
| 220 } | 197 } |
| 221 ASSERT_TRUE(false); | 198 ASSERT_TRUE(false); |
| 222 } | 199 } |
| 223 | 200 |
| 224 void WaitForDecodedFrame() const { | 201 void WaitForDecodedFrame() { |
| 225 int64_t start_ms = rtc::TimeMillis(); | 202 int64_t start_ms = rtc::TimeMillis(); |
| 226 while (rtc::TimeMillis() - start_ms < kMaxWaitDecTimeMs) { | 203 while (rtc::TimeMillis() - start_ms < kMaxWaitDecTimeMs) { |
| 227 if (decode_complete_callback_->DecodeComplete()) { | 204 if (decoded_cb_.DecodeComplete()) |
| 228 return; | 205 return; |
| 229 } | |
| 230 } | 206 } |
| 231 ASSERT_TRUE(false); | 207 ASSERT_TRUE(false); |
| 232 } | 208 } |
| 233 | 209 |
| 234 void ExpectFrameWith(int16_t picture_id, | 210 void ExpectFrameWith(int16_t picture_id, |
| 235 int tl0_pic_idx, | 211 int tl0_pic_idx, |
| 236 uint8_t temporal_idx) { | 212 uint8_t temporal_idx) { |
| 237 WaitForEncodedFrame(); | 213 WaitForEncodedFrame(); |
| 238 EXPECT_EQ(picture_id, codec_specific_info_.codecSpecific.VP8.pictureId); | 214 EXPECT_EQ(picture_id, |
| 239 EXPECT_EQ(tl0_pic_idx, codec_specific_info_.codecSpecific.VP8.tl0PicIdx); | 215 encoded_cb_.codec_specific_info_.codecSpecific.VP8.pictureId); |
| 240 EXPECT_EQ(temporal_idx, codec_specific_info_.codecSpecific.VP8.temporalIdx); | 216 EXPECT_EQ(tl0_pic_idx, |
| 217 encoded_cb_.codec_specific_info_.codecSpecific.VP8.tl0PicIdx); | |
| 218 EXPECT_EQ(temporal_idx, | |
| 219 encoded_cb_.codec_specific_info_.codecSpecific.VP8.temporalIdx); | |
| 241 } | 220 } |
| 242 | 221 |
| 243 test::ScopedFieldTrials override_field_trials_; | 222 test::ScopedFieldTrials override_field_trials_; |
| 244 std::unique_ptr<Vp8UnitTestEncodeCompleteCallback> encode_complete_callback_; | 223 EncodedImageCallbackTestImpl encoded_cb_; |
| 245 std::unique_ptr<Vp8UnitTestDecodeCompleteCallback> decode_complete_callback_; | 224 DecodedImageCallbackTestImpl decoded_cb_; |
| 246 std::unique_ptr<VideoFrame> input_frame_; | 225 std::unique_ptr<VideoFrame> input_frame_; |
| 247 std::unique_ptr<VideoEncoder> encoder_; | 226 const std::unique_ptr<VideoEncoder> encoder_; |
| 248 std::unique_ptr<VideoDecoder> decoder_; | 227 const std::unique_ptr<VideoDecoder> decoder_; |
| 249 EncodedImage encoded_frame_; | |
| 250 CodecSpecificInfo codec_specific_info_; | |
| 251 rtc::Optional<VideoFrame> decoded_frame_; | |
| 252 rtc::Optional<uint8_t> decoded_qp_; | |
| 253 VideoCodec codec_settings_; | 228 VideoCodec codec_settings_; |
| 254 TemporalLayersFactory tl_factory_; | 229 TemporalLayersFactory tl_factory_; |
| 255 }; | 230 }; |
| 256 | 231 |
| 257 TEST_F(TestVp8Impl, EncodeFrame) { | 232 TEST_F(TestVp8Impl, EncodeFrame) { |
| 258 SetUpEncodeDecode(); | 233 InitEncodeDecode(); |
| 259 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 234 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 260 encoder_->Encode(*input_frame_, nullptr, nullptr)); | 235 encoder_->Encode(*input_frame_, nullptr, nullptr)); |
| 261 WaitForEncodedFrame(); | 236 WaitForEncodedFrame(); |
| 262 } | 237 } |
| 263 | 238 |
| 264 TEST_F(TestVp8Impl, EncoderParameterTest) { | 239 TEST_F(TestVp8Impl, EncoderParameterTest) { |
| 265 codec_settings_.maxBitrate = 0; | 240 codec_settings_.maxBitrate = 0; |
| 266 codec_settings_.width = 1440; | 241 codec_settings_.width = 1440; |
| 267 codec_settings_.height = 1080; | 242 codec_settings_.height = 1080; |
| 268 | 243 |
| 269 // Calls before InitEncode(). | 244 // Calls before InitEncode(). |
| 270 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); | 245 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); |
| 271 const int kBitrateKbps = 300; | 246 const int kBitrateBps = 300000; |
| 272 BitrateAllocation bitrate_allocation; | 247 BitrateAllocation bitrate_allocation; |
| 273 bitrate_allocation.SetBitrate(0, 0, kBitrateKbps * 1000); | 248 bitrate_allocation.SetBitrate(0, 0, kBitrateBps); |
| 274 EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED, | 249 EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED, |
| 275 encoder_->SetRateAllocation(bitrate_allocation, | 250 encoder_->SetRateAllocation(bitrate_allocation, |
| 276 codec_settings_.maxFramerate)); | 251 codec_settings_.maxFramerate)); |
| 277 | |
| 278 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 252 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 279 encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); | 253 encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); |
| 254 } | |
| 280 | 255 |
| 281 // Decoder parameter tests. | 256 TEST_F(TestVp8Impl, DecoderParameterTest) { |
| 282 // Calls before InitDecode(). | 257 // Calls before InitDecode(). |
| 283 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release()); | 258 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release()); |
| 284 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 259 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 285 decoder_->InitDecode(&codec_settings_, kNumCores)); | 260 decoder_->InitDecode(&codec_settings_, kNumCores)); |
| 286 } | 261 } |
| 287 | 262 |
| 288 // We only test the encoder here, since the decoded frame rotation is set based | 263 // We only test the encoder here, since the decoded frame rotation is set based |
| 289 // on the CVO RTP header extension in VCMDecodedFrameCallback::Decoded. | 264 // on the CVO RTP header extension in VCMDecodedFrameCallback::Decoded. |
| 290 // TODO(brandtr): Consider passing through the rotation flag through the decoder | 265 // TODO(brandtr): Consider passing through the rotation flag through the decoder |
| 291 // in the same way as done in the encoder. | 266 // in the same way as done in the encoder. |
| 292 TEST_F(TestVp8Impl, EncodedRotationEqualsInputRotation) { | 267 TEST_F(TestVp8Impl, EncodedRotationEqualsInputRotation) { |
| 293 SetUpEncodeDecode(); | 268 InitEncodeDecode(); |
| 294 | 269 |
| 295 input_frame_->set_rotation(kVideoRotation_0); | 270 input_frame_->set_rotation(kVideoRotation_0); |
| 296 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 271 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 297 encoder_->Encode(*input_frame_, nullptr, nullptr)); | 272 encoder_->Encode(*input_frame_, nullptr, nullptr)); |
| 298 WaitForEncodedFrame(); | 273 WaitForEncodedFrame(); |
| 299 EXPECT_EQ(kVideoRotation_0, encoded_frame_.rotation_); | 274 EXPECT_EQ(kVideoRotation_0, encoded_cb_.encoded_frame_.rotation_); |
| 300 | 275 |
| 301 input_frame_->set_rotation(kVideoRotation_90); | 276 input_frame_->set_rotation(kVideoRotation_90); |
| 302 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 277 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 303 encoder_->Encode(*input_frame_, nullptr, nullptr)); | 278 encoder_->Encode(*input_frame_, nullptr, nullptr)); |
| 304 WaitForEncodedFrame(); | 279 WaitForEncodedFrame(); |
| 305 EXPECT_EQ(kVideoRotation_90, encoded_frame_.rotation_); | 280 EXPECT_EQ(kVideoRotation_90, encoded_cb_.encoded_frame_.rotation_); |
| 306 } | 281 } |
| 307 | 282 |
| 308 TEST_F(TestVp8Impl, DecodedQpEqualsEncodedQp) { | 283 TEST_F(TestVp8Impl, DecodedQpEqualsEncodedQp) { |
| 309 SetUpEncodeDecode(); | 284 InitEncodeDecode(); |
| 310 encoder_->Encode(*input_frame_, nullptr, nullptr); | 285 encoder_->Encode(*input_frame_, nullptr, nullptr); |
| 311 WaitForEncodedFrame(); | 286 WaitForEncodedFrame(); |
| 312 // First frame should be a key frame. | 287 // First frame should be a key frame. |
| 313 encoded_frame_._frameType = kVideoFrameKey; | 288 encoded_cb_.encoded_frame_._frameType = kVideoFrameKey; |
| 314 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 289 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 315 decoder_->Decode(encoded_frame_, false, nullptr)); | 290 decoder_->Decode(encoded_cb_.encoded_frame_, false, nullptr)); |
| 316 WaitForDecodedFrame(); | 291 WaitForDecodedFrame(); |
| 317 ASSERT_TRUE(decoded_frame_); | 292 EXPECT_GT(I420PSNR(input_frame_.get(), &*decoded_cb_.frame_), 36); |
| 318 EXPECT_GT(I420PSNR(input_frame_.get(), &*decoded_frame_), 36); | 293 EXPECT_EQ(encoded_cb_.encoded_frame_.qp_, *decoded_cb_.qp_); |
| 319 ASSERT_TRUE(decoded_qp_); | |
| 320 EXPECT_EQ(encoded_frame_.qp_, *decoded_qp_); | |
| 321 } | 294 } |
| 322 | 295 |
| 323 #if defined(WEBRTC_ANDROID) | 296 #if defined(WEBRTC_ANDROID) |
| 324 #define MAYBE_AlignedStrideEncodeDecode DISABLED_AlignedStrideEncodeDecode | 297 #define MAYBE_AlignedStrideEncodeDecode DISABLED_AlignedStrideEncodeDecode |
| 325 #else | 298 #else |
| 326 #define MAYBE_AlignedStrideEncodeDecode AlignedStrideEncodeDecode | 299 #define MAYBE_AlignedStrideEncodeDecode AlignedStrideEncodeDecode |
| 327 #endif | 300 #endif |
| 328 TEST_F(TestVp8Impl, MAYBE_AlignedStrideEncodeDecode) { | 301 TEST_F(TestVp8Impl, MAYBE_AlignedStrideEncodeDecode) { |
| 329 SetUpEncodeDecode(); | 302 InitEncodeDecode(); |
| 330 encoder_->Encode(*input_frame_, nullptr, nullptr); | 303 encoder_->Encode(*input_frame_, nullptr, nullptr); |
| 331 WaitForEncodedFrame(); | 304 WaitForEncodedFrame(); |
| 332 // First frame should be a key frame. | 305 // First frame should be a key frame. |
| 333 encoded_frame_._frameType = kVideoFrameKey; | 306 encoded_cb_.encoded_frame_._frameType = kVideoFrameKey; |
| 334 encoded_frame_.ntp_time_ms_ = kTestNtpTimeMs; | 307 encoded_cb_.encoded_frame_.ntp_time_ms_ = kTestNtpTimeMs; |
| 335 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 308 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 336 decoder_->Decode(encoded_frame_, false, nullptr)); | 309 decoder_->Decode(encoded_cb_.encoded_frame_, false, nullptr)); |
| 337 WaitForDecodedFrame(); | 310 WaitForDecodedFrame(); |
| 338 ASSERT_TRUE(decoded_frame_); | |
| 339 // Compute PSNR on all planes (faster than SSIM). | 311 // Compute PSNR on all planes (faster than SSIM). |
| 340 EXPECT_GT(I420PSNR(input_frame_.get(), &*decoded_frame_), 36); | 312 EXPECT_GT(I420PSNR(input_frame_.get(), &*decoded_cb_.frame_), 36); |
| 341 EXPECT_EQ(kTestTimestamp, decoded_frame_->timestamp()); | 313 EXPECT_EQ(kTestTimestamp, decoded_cb_.frame_->timestamp()); |
| 342 EXPECT_EQ(kTestNtpTimeMs, decoded_frame_->ntp_time_ms()); | 314 EXPECT_EQ(kTestNtpTimeMs, decoded_cb_.frame_->ntp_time_ms()); |
| 343 } | 315 } |
| 344 | 316 |
| 345 #if defined(WEBRTC_ANDROID) | 317 #if defined(WEBRTC_ANDROID) |
| 346 #define MAYBE_DecodeWithACompleteKeyFrame DISABLED_DecodeWithACompleteKeyFrame | 318 #define MAYBE_DecodeWithACompleteKeyFrame DISABLED_DecodeWithACompleteKeyFrame |
| 347 #else | 319 #else |
| 348 #define MAYBE_DecodeWithACompleteKeyFrame DecodeWithACompleteKeyFrame | 320 #define MAYBE_DecodeWithACompleteKeyFrame DecodeWithACompleteKeyFrame |
| 349 #endif | 321 #endif |
| 350 TEST_F(TestVp8Impl, MAYBE_DecodeWithACompleteKeyFrame) { | 322 TEST_F(TestVp8Impl, MAYBE_DecodeWithACompleteKeyFrame) { |
| 351 SetUpEncodeDecode(); | 323 InitEncodeDecode(); |
| 352 encoder_->Encode(*input_frame_, nullptr, nullptr); | 324 encoder_->Encode(*input_frame_, nullptr, nullptr); |
| 353 WaitForEncodedFrame(); | 325 WaitForEncodedFrame(); |
| 354 // Setting complete to false -> should return an error. | 326 // Setting complete to false -> should return an error. |
| 355 encoded_frame_._completeFrame = false; | 327 encoded_cb_.encoded_frame_._completeFrame = false; |
| 356 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, | 328 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, |
| 357 decoder_->Decode(encoded_frame_, false, nullptr)); | 329 decoder_->Decode(encoded_cb_.encoded_frame_, false, nullptr)); |
| 358 // Setting complete back to true. Forcing a delta frame. | 330 // Setting complete back to true. Forcing a delta frame. |
| 359 encoded_frame_._frameType = kVideoFrameDelta; | 331 encoded_cb_.encoded_frame_._frameType = kVideoFrameDelta; |
| 360 encoded_frame_._completeFrame = true; | 332 encoded_cb_.encoded_frame_._completeFrame = true; |
| 361 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, | 333 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, |
| 362 decoder_->Decode(encoded_frame_, false, nullptr)); | 334 decoder_->Decode(encoded_cb_.encoded_frame_, false, nullptr)); |
| 363 // Now setting a key frame. | 335 // Now setting a key frame. |
| 364 encoded_frame_._frameType = kVideoFrameKey; | 336 encoded_cb_.encoded_frame_._frameType = kVideoFrameKey; |
| 365 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 337 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 366 decoder_->Decode(encoded_frame_, false, nullptr)); | 338 decoder_->Decode(encoded_cb_.encoded_frame_, false, nullptr)); |
| 367 ASSERT_TRUE(decoded_frame_); | 339 ASSERT_TRUE(decoded_cb_.frame_); |
| 368 EXPECT_GT(I420PSNR(input_frame_.get(), &*decoded_frame_), 36); | 340 EXPECT_GT(I420PSNR(input_frame_.get(), &*decoded_cb_.frame_), 36); |
| 369 } | 341 } |
| 370 | 342 |
| 371 TEST_F(TestVp8Impl, EncoderRetainsRtpStateAfterRelease) { | 343 TEST_F(TestVp8Impl, EncoderRetainsRtpStateAfterRelease) { |
| 372 SetUpEncodeDecode(); | 344 InitEncodeDecode(); |
| 373 // Override default settings. | 345 // Override default settings. |
| 374 codec_settings_.VP8()->numberOfTemporalLayers = 2; | 346 codec_settings_.VP8()->numberOfTemporalLayers = 2; |
| 375 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 347 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 376 encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); | 348 encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); |
| 377 | 349 |
| 378 // Temporal layer 0. | 350 // Temporal layer 0. |
| 379 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 351 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 380 encoder_->Encode(*input_frame_, nullptr, nullptr)); | 352 encoder_->Encode(*input_frame_, nullptr, nullptr)); |
| 381 WaitForEncodedFrame(); | 353 WaitForEncodedFrame(); |
| 382 EXPECT_EQ(0, codec_specific_info_.codecSpecific.VP8.temporalIdx); | 354 EXPECT_EQ(0, encoded_cb_.codec_specific_info_.codecSpecific.VP8.temporalIdx); |
| 383 int16_t picture_id = codec_specific_info_.codecSpecific.VP8.pictureId; | 355 int16_t picture_id = |
| 384 int tl0_pic_idx = codec_specific_info_.codecSpecific.VP8.tl0PicIdx; | 356 encoded_cb_.codec_specific_info_.codecSpecific.VP8.pictureId; |
| 357 int tl0_pic_idx = | |
| 358 encoded_cb_.codec_specific_info_.codecSpecific.VP8.tl0PicIdx; | |
| 385 | 359 |
| 386 // Temporal layer 1. | 360 // Temporal layer 1. |
| 387 input_frame_->set_timestamp(input_frame_->timestamp() + | 361 input_frame_->set_timestamp(input_frame_->timestamp() + |
| 388 kTimestampIncrementPerFrame); | 362 kTimestampIncrementPerFrame); |
| 389 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 363 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 390 encoder_->Encode(*input_frame_, nullptr, nullptr)); | 364 encoder_->Encode(*input_frame_, nullptr, nullptr)); |
| 391 ExpectFrameWith((picture_id + 1) % (1 << 15), tl0_pic_idx, 1); | 365 ExpectFrameWith((picture_id + 1) % (1 << 15), tl0_pic_idx, 1); |
| 392 | 366 |
| 393 // Temporal layer 0. | 367 // Temporal layer 0. |
| 394 input_frame_->set_timestamp(input_frame_->timestamp() + | 368 input_frame_->set_timestamp(input_frame_->timestamp() + |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 477 codec_settings_.VP8()->automaticResizeOn = true; | 451 codec_settings_.VP8()->automaticResizeOn = true; |
| 478 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 452 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 479 encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); | 453 encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); |
| 480 | 454 |
| 481 VideoEncoder::ScalingSettings settings = encoder_->GetScalingSettings(); | 455 VideoEncoder::ScalingSettings settings = encoder_->GetScalingSettings(); |
| 482 EXPECT_TRUE(settings.enabled); | 456 EXPECT_TRUE(settings.enabled); |
| 483 EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame); | 457 EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame); |
| 484 } | 458 } |
| 485 | 459 |
| 486 } // namespace webrtc | 460 } // namespace webrtc |
| OLD | NEW |