Index: webrtc/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc |
diff --git a/webrtc/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc b/webrtc/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc |
index d9871873b8e96d218da410a2eec7dacc01618d58..f5fcee3344c1c46bd374fd86b493b792f6a2ad56 100644 |
--- a/webrtc/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc |
+++ b/webrtc/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc |
@@ -35,9 +35,8 @@ void Calc16ByteAlignedStride(int width, int* stride_y, int* stride_uv) { |
*stride_uv = 16 * ((width + 31) / 32); |
} |
-enum { kMaxWaitEncTimeMs = 100 }; |
-enum { kMaxWaitDecTimeMs = 25 }; |
- |
+constexpr int64_t kMaxWaitEncTimeMs = 100; |
+constexpr int64_t kMaxWaitDecTimeMs = 25; |
constexpr uint32_t kTestTimestamp = 123; |
constexpr int64_t kTestNtpTimeMs = 456; |
constexpr uint32_t kTimestampIncrementPerFrame = 3000; |
@@ -45,25 +44,29 @@ constexpr int kNumCores = 1; |
constexpr size_t kMaxPayloadSize = 1440; |
constexpr int kMinPixelsPerFrame = 12345; |
constexpr int kDefaultMinPixelsPerFrame = 320 * 180; |
- |
+constexpr int kWidth = 172; |
+constexpr int kHeight = 144; |
} // namespace |
-// TODO(mikhal): Replace these with mocks. |
class Vp8UnitTestEncodeCompleteCallback : public webrtc::EncodedImageCallback { |
public: |
Vp8UnitTestEncodeCompleteCallback(EncodedImage* frame, |
- CodecSpecificInfo* codec_specific_info, |
- unsigned int decoderSpecificSize, |
- void* decoderSpecificInfo) |
+ CodecSpecificInfo* codec_specific_info) |
: encoded_frame_(frame), |
codec_specific_info_(codec_specific_info), |
encode_complete_(false) {} |
- Result OnEncodedImage(const EncodedImage& encoded_frame_, |
+ Result OnEncodedImage(const EncodedImage& encoded_frame, |
const CodecSpecificInfo* codec_specific_info, |
const RTPFragmentationHeader* fragmentation) override; |
bool EncodeComplete(); |
+ void VerifyQp(const EncodedImage& encoded_frame) const { |
brandtr
2017/08/21 11:27:33
Maybe add a comment what this function does?
åsapersson
2017/08/21 11:53:11
Renamed function.
|
+ int qp; |
+ ASSERT_TRUE(vp8::GetQp(encoded_frame._buffer, encoded_frame._length, &qp)); |
+ EXPECT_EQ(encoded_frame.qp_, qp) << "Encoder QP != bitstream QP."; |
+ } |
+ |
private: |
EncodedImage* const encoded_frame_; |
CodecSpecificInfo* const codec_specific_info_; |
@@ -76,23 +79,19 @@ Vp8UnitTestEncodeCompleteCallback::OnEncodedImage( |
const EncodedImage& encoded_frame, |
const CodecSpecificInfo* codec_specific_info, |
const RTPFragmentationHeader* fragmentation) { |
- if (encoded_frame_->_size < encoded_frame._length) { |
+ EXPECT_GT(encoded_frame._length, 0u); |
+ VerifyQp(encoded_frame); |
+ |
+ if (encoded_frame_->_size != encoded_frame._size) { |
delete[] encoded_frame_->_buffer; |
- frame_buffer_.reset(new uint8_t[encoded_frame._length]); |
- encoded_frame_->_buffer = frame_buffer_.get(); |
- encoded_frame_->_size = encoded_frame._length; |
+ frame_buffer_.reset(new uint8_t[encoded_frame._size]); |
} |
- memcpy(encoded_frame_->_buffer, encoded_frame._buffer, encoded_frame._length); |
- encoded_frame_->_length = encoded_frame._length; |
- encoded_frame_->_encodedWidth = encoded_frame._encodedWidth; |
- encoded_frame_->_encodedHeight = encoded_frame._encodedHeight; |
- encoded_frame_->_timeStamp = encoded_frame._timeStamp; |
- encoded_frame_->_frameType = encoded_frame._frameType; |
- encoded_frame_->_completeFrame = encoded_frame._completeFrame; |
- encoded_frame_->rotation_ = encoded_frame.rotation_; |
- encoded_frame_->qp_ = encoded_frame.qp_; |
- codec_specific_info_->codecType = codec_specific_info->codecType; |
+ memcpy(frame_buffer_.get(), encoded_frame._buffer, encoded_frame._length); |
+ *encoded_frame_ = encoded_frame; |
+ encoded_frame_->_buffer = frame_buffer_.get(); |
+ |
// Skip |codec_name|, to avoid allocating. |
+ codec_specific_info_->codecType = codec_specific_info->codecType; |
codec_specific_info_->codecSpecific = codec_specific_info->codecSpecific; |
encode_complete_ = true; |
return Result(Result::OK, 0); |
@@ -110,7 +109,7 @@ class Vp8UnitTestDecodeCompleteCallback : public webrtc::DecodedImageCallback { |
public: |
explicit Vp8UnitTestDecodeCompleteCallback(rtc::Optional<VideoFrame>* frame, |
rtc::Optional<uint8_t>* qp) |
- : decoded_frame_(frame), decoded_qp_(qp), decode_complete(false) {} |
+ : decoded_frame_(frame), decoded_qp_(qp), decode_complete_(false) {} |
int32_t Decoded(VideoFrame& frame) override { |
RTC_NOTREACHED(); |
return -1; |
@@ -127,12 +126,12 @@ class Vp8UnitTestDecodeCompleteCallback : public webrtc::DecodedImageCallback { |
private: |
rtc::Optional<VideoFrame>* decoded_frame_; |
rtc::Optional<uint8_t>* decoded_qp_; |
- bool decode_complete; |
+ bool decode_complete_; |
}; |
bool Vp8UnitTestDecodeCompleteCallback::DecodeComplete() { |
- if (decode_complete) { |
- decode_complete = false; |
+ if (decode_complete_) { |
+ decode_complete_ = false; |
return true; |
} |
return false; |
@@ -142,9 +141,11 @@ void Vp8UnitTestDecodeCompleteCallback::Decoded( |
VideoFrame& frame, |
rtc::Optional<int32_t> decode_time_ms, |
rtc::Optional<uint8_t> qp) { |
+ EXPECT_GT(frame.width(), 0); |
+ EXPECT_GT(frame.height(), 0); |
*decoded_frame_ = rtc::Optional<VideoFrame>(frame); |
*decoded_qp_ = qp; |
- decode_complete = true; |
+ decode_complete_ = true; |
} |
class TestVp8Impl : public ::testing::Test { |
@@ -156,28 +157,26 @@ class TestVp8Impl : public ::testing::Test { |
virtual void SetUp() { |
encoder_.reset(VP8Encoder::Create()); |
decoder_.reset(VP8Decoder::Create()); |
- memset(&codec_settings_, 0, sizeof(codec_settings_)); |
encode_complete_callback_.reset(new Vp8UnitTestEncodeCompleteCallback( |
- &encoded_frame_, &codec_specific_info_, 0, nullptr)); |
+ &encoded_frame_, &codec_specific_info_)); |
decode_complete_callback_.reset( |
new Vp8UnitTestDecodeCompleteCallback(&decoded_frame_, &decoded_qp_)); |
encoder_->RegisterEncodeCompleteCallback(encode_complete_callback_.get()); |
decoder_->RegisterDecodeCompleteCallback(decode_complete_callback_.get()); |
+ |
+ SetupCodecSettings(); |
+ |
// Using a QCIF image (aligned stride (u,v planes) > width). |
// Processing only one frame. |
- source_file_ = fopen(test::ResourcePath("paris_qcif", "yuv").c_str(), "rb"); |
- ASSERT_TRUE(source_file_ != nullptr); |
+ FILE* file = fopen(test::ResourcePath("paris_qcif", "yuv").c_str(), "rb"); |
+ ASSERT_TRUE(file != nullptr); |
rtc::scoped_refptr<I420BufferInterface> compact_buffer( |
- test::ReadI420Buffer(kWidth, kHeight, source_file_)); |
+ test::ReadI420Buffer(kWidth, kHeight, file)); |
ASSERT_TRUE(compact_buffer); |
- codec_settings_.width = kWidth; |
- codec_settings_.height = kHeight; |
- const int kFramerate = 30; |
- codec_settings_.maxFramerate = kFramerate; |
// Setting aligned stride values. |
int stride_uv; |
int stride_y; |
- Calc16ByteAlignedStride(codec_settings_.width, &stride_y, &stride_uv); |
+ Calc16ByteAlignedStride(kWidth, &stride_y, &stride_uv); |
EXPECT_EQ(stride_y, 176); |
EXPECT_EQ(stride_uv, 96); |
@@ -187,19 +186,24 @@ class TestVp8Impl : public ::testing::Test { |
// No scaling in our case, just a copy, to add stride to the image. |
stride_buffer->ScaleFrom(*compact_buffer); |
- input_frame_.reset( |
- new VideoFrame(stride_buffer, kVideoRotation_0, 0)); |
+ input_frame_.reset(new VideoFrame(stride_buffer, kVideoRotation_0, 0)); |
input_frame_->set_timestamp(kTestTimestamp); |
+ fclose(file); |
} |
- void SetUpEncodeDecode() { |
- codec_settings_.startBitrate = 300; |
+ void SetupCodecSettings() { |
+ webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings_); |
codec_settings_.maxBitrate = 4000; |
- codec_settings_.qpMax = 56; |
+ codec_settings_.width = kWidth; |
+ codec_settings_.height = kHeight; |
codec_settings_.VP8()->denoisingOn = true; |
+ codec_settings_.VP8()->frameDroppingOn = false; |
+ codec_settings_.VP8()->automaticResizeOn = false; |
+ codec_settings_.VP8()->complexity = kComplexityNormal; |
codec_settings_.VP8()->tl_factory = &tl_factory_; |
- codec_settings_.VP8()->numberOfTemporalLayers = 1; |
+ } |
+ void SetUpEncodeDecode() { |
EXPECT_EQ( |
WEBRTC_VIDEO_CODEC_OK, |
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); |
@@ -207,44 +211,38 @@ class TestVp8Impl : public ::testing::Test { |
decoder_->InitDecode(&codec_settings_, kNumCores)); |
} |
- size_t WaitForEncodedFrame() const { |
- int64_t startTime = rtc::TimeMillis(); |
- while (rtc::TimeMillis() - startTime < kMaxWaitEncTimeMs) { |
+ void WaitForEncodedFrame() const { |
+ int64_t start_ms = rtc::TimeMillis(); |
+ while (rtc::TimeMillis() - start_ms < kMaxWaitEncTimeMs) { |
if (encode_complete_callback_->EncodeComplete()) { |
- return encoded_frame_._length; |
+ return; |
} |
} |
- return 0; |
+ ASSERT_TRUE(false); |
} |
- size_t WaitForDecodedFrame() const { |
- int64_t startTime = rtc::TimeMillis(); |
- while (rtc::TimeMillis() - startTime < kMaxWaitDecTimeMs) { |
+ void WaitForDecodedFrame() const { |
+ int64_t start_ms = rtc::TimeMillis(); |
+ while (rtc::TimeMillis() - start_ms < kMaxWaitDecTimeMs) { |
if (decode_complete_callback_->DecodeComplete()) { |
- return CalcBufferSize(VideoType::kI420, decoded_frame_->width(), |
- decoded_frame_->height()); |
+ return; |
} |
} |
- return 0; |
+ ASSERT_TRUE(false); |
} |
void ExpectFrameWith(int16_t picture_id, |
int tl0_pic_idx, |
uint8_t temporal_idx) { |
- ASSERT_TRUE(WaitForEncodedFrame()); |
+ WaitForEncodedFrame(); |
EXPECT_EQ(picture_id, codec_specific_info_.codecSpecific.VP8.pictureId); |
EXPECT_EQ(tl0_pic_idx, codec_specific_info_.codecSpecific.VP8.tl0PicIdx); |
EXPECT_EQ(temporal_idx, codec_specific_info_.codecSpecific.VP8.temporalIdx); |
} |
- const int kWidth = 172; |
- const int kHeight = 144; |
- |
test::ScopedFieldTrials override_field_trials_; |
std::unique_ptr<Vp8UnitTestEncodeCompleteCallback> encode_complete_callback_; |
std::unique_ptr<Vp8UnitTestDecodeCompleteCallback> decode_complete_callback_; |
- std::unique_ptr<uint8_t[]> source_buffer_; |
- FILE* source_file_; |
std::unique_ptr<VideoFrame> input_frame_; |
std::unique_ptr<VideoEncoder> encoder_; |
std::unique_ptr<VideoDecoder> decoder_; |
@@ -256,24 +254,23 @@ class TestVp8Impl : public ::testing::Test { |
TemporalLayersFactory tl_factory_; |
}; |
+TEST_F(TestVp8Impl, EncodeFrame) { |
+ SetUpEncodeDecode(); |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
+ encoder_->Encode(*input_frame_, nullptr, nullptr)); |
+ WaitForEncodedFrame(); |
+} |
+ |
TEST_F(TestVp8Impl, EncoderParameterTest) { |
- strncpy(codec_settings_.plName, "VP8", 31); |
- codec_settings_.plType = 126; |
codec_settings_.maxBitrate = 0; |
- codec_settings_.minBitrate = 0; |
codec_settings_.width = 1440; |
codec_settings_.height = 1080; |
- codec_settings_.maxFramerate = 30; |
- codec_settings_.startBitrate = 300; |
- codec_settings_.qpMax = 56; |
- codec_settings_.VP8()->complexity = kComplexityNormal; |
- codec_settings_.VP8()->numberOfTemporalLayers = 1; |
- codec_settings_.VP8()->tl_factory = &tl_factory_; |
+ |
// Calls before InitEncode(). |
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); |
- int bit_rate = 300; |
+ const int kBitrate = 300; |
brandtr
2017/08/21 11:27:33
kBitrateKbps
åsapersson
2017/08/21 11:53:11
Done.
|
BitrateAllocation bitrate_allocation; |
- bitrate_allocation.SetBitrate(0, 0, bit_rate * 1000); |
+ bitrate_allocation.SetBitrate(0, 0, kBitrate * 1000); |
EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED, |
encoder_->SetRateAllocation(bitrate_allocation, |
codec_settings_.maxFramerate)); |
@@ -311,30 +308,18 @@ TEST_F(TestVp8Impl, EncodedRotationEqualsInputRotation) { |
TEST_F(TestVp8Impl, DecodedQpEqualsEncodedQp) { |
SetUpEncodeDecode(); |
encoder_->Encode(*input_frame_, nullptr, nullptr); |
- EXPECT_GT(WaitForEncodedFrame(), 0u); |
+ WaitForEncodedFrame(); |
// First frame should be a key frame. |
encoded_frame_._frameType = kVideoFrameKey; |
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
decoder_->Decode(encoded_frame_, false, nullptr)); |
- EXPECT_GT(WaitForDecodedFrame(), 0u); |
+ WaitForDecodedFrame(); |
ASSERT_TRUE(decoded_frame_); |
EXPECT_GT(I420PSNR(input_frame_.get(), &*decoded_frame_), 36); |
ASSERT_TRUE(decoded_qp_); |
EXPECT_EQ(encoded_frame_.qp_, *decoded_qp_); |
} |
-TEST_F(TestVp8Impl, ParserQpEqualsEncodedQp) { |
- SetUpEncodeDecode(); |
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
- encoder_->Encode(*input_frame_, nullptr, nullptr)); |
- EXPECT_GT(WaitForEncodedFrame(), 0u); |
- |
- int qp = 0; |
- ASSERT_TRUE(vp8::GetQp(encoded_frame_._buffer, encoded_frame_._length, &qp)); |
- |
- EXPECT_EQ(encoded_frame_.qp_, qp); |
-} |
- |
#if defined(WEBRTC_ANDROID) |
#define MAYBE_AlignedStrideEncodeDecode DISABLED_AlignedStrideEncodeDecode |
#else |
@@ -343,13 +328,13 @@ TEST_F(TestVp8Impl, ParserQpEqualsEncodedQp) { |
TEST_F(TestVp8Impl, MAYBE_AlignedStrideEncodeDecode) { |
SetUpEncodeDecode(); |
encoder_->Encode(*input_frame_, nullptr, nullptr); |
- EXPECT_GT(WaitForEncodedFrame(), 0u); |
+ WaitForEncodedFrame(); |
// First frame should be a key frame. |
encoded_frame_._frameType = kVideoFrameKey; |
encoded_frame_.ntp_time_ms_ = kTestNtpTimeMs; |
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
decoder_->Decode(encoded_frame_, false, nullptr)); |
- EXPECT_GT(WaitForDecodedFrame(), 0u); |
+ WaitForDecodedFrame(); |
ASSERT_TRUE(decoded_frame_); |
// Compute PSNR on all planes (faster than SSIM). |
EXPECT_GT(I420PSNR(input_frame_.get(), &*decoded_frame_), 36); |
@@ -365,7 +350,7 @@ TEST_F(TestVp8Impl, MAYBE_AlignedStrideEncodeDecode) { |
TEST_F(TestVp8Impl, MAYBE_DecodeWithACompleteKeyFrame) { |
SetUpEncodeDecode(); |
encoder_->Encode(*input_frame_, nullptr, nullptr); |
- EXPECT_GT(WaitForEncodedFrame(), 0u); |
+ WaitForEncodedFrame(); |
// Setting complete to false -> should return an error. |
encoded_frame_._completeFrame = false; |
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, |
@@ -393,7 +378,7 @@ TEST_F(TestVp8Impl, EncoderRetainsRtpStateAfterRelease) { |
// Temporal layer 0. |
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
encoder_->Encode(*input_frame_, nullptr, nullptr)); |
- ASSERT_TRUE(WaitForEncodedFrame()); |
+ WaitForEncodedFrame(); |
EXPECT_EQ(0, codec_specific_info_.codecSpecific.VP8.temporalIdx); |
int16_t picture_id = codec_specific_info_.codecSpecific.VP8.pictureId; |
int tl0_pic_idx = codec_specific_info_.codecSpecific.VP8.tl0PicIdx; |
@@ -460,23 +445,21 @@ TEST_F(TestVp8Impl, EncoderRetainsRtpStateAfterRelease) { |
} |
TEST_F(TestVp8Impl, ScalingDisabledIfAutomaticResizeOff) { |
- webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings_); |
- codec_settings_.VP8()->tl_factory = &tl_factory_; |
+ codec_settings_.VP8()->frameDroppingOn = true; |
codec_settings_.VP8()->automaticResizeOn = false; |
- |
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); |
+ |
VideoEncoder::ScalingSettings settings = encoder_->GetScalingSettings(); |
EXPECT_FALSE(settings.enabled); |
} |
TEST_F(TestVp8Impl, ScalingEnabledIfAutomaticResizeOn) { |
- webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings_); |
- codec_settings_.VP8()->tl_factory = &tl_factory_; |
+ codec_settings_.VP8()->frameDroppingOn = true; |
codec_settings_.VP8()->automaticResizeOn = true; |
- |
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); |
+ |
VideoEncoder::ScalingSettings settings = encoder_->GetScalingSettings(); |
EXPECT_TRUE(settings.enabled); |
EXPECT_EQ(kDefaultMinPixelsPerFrame, settings.min_pixels_per_frame); |
@@ -490,12 +473,11 @@ class TestVp8ImplWithForcedFallbackEnabled : public TestVp8Impl { |
}; |
TEST_F(TestVp8ImplWithForcedFallbackEnabled, MinPixelsPerFrameConfigured) { |
- webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings_); |
- codec_settings_.VP8()->tl_factory = &tl_factory_; |
+ codec_settings_.VP8()->frameDroppingOn = true; |
codec_settings_.VP8()->automaticResizeOn = true; |
- |
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
encoder_->InitEncode(&codec_settings_, kNumCores, kMaxPayloadSize)); |
+ |
VideoEncoder::ScalingSettings settings = encoder_->GetScalingSettings(); |
EXPECT_TRUE(settings.enabled); |
EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame); |