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

Unified Diff: webrtc/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc

Issue 2833493003: Don't re-randomize picture_id/tl0_pic_idx when re-initializing internal encoders. (Closed)
Patch Set: Change back TimeMills() -> TimeMicros(). Created 3 years, 8 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 side-by-side diff with in-line comments
Download patch
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 c4c600d67e328eb96f00cf7e68346eba07db9353..ece5b63f051695fe7a79b265ccf67cde210a40b4 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
@@ -19,6 +19,7 @@
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
#include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h"
+#include "webrtc/modules/video_coding/include/video_codec_interface.h"
#include "webrtc/test/frame_utils.h"
#include "webrtc/test/gtest.h"
#include "webrtc/test/testsupport/fileutils.h"
@@ -26,26 +27,31 @@
namespace webrtc {
namespace {
+
void Calc16ByteAlignedStride(int width, int* stride_y, int* stride_uv) {
*stride_y = 16 * ((width + 15) / 16);
*stride_uv = 16 * ((width + 31) / 32);
}
-} // Anonymous namespace
-
enum { kMaxWaitEncTimeMs = 100 };
enum { kMaxWaitDecTimeMs = 25 };
-static const uint32_t kTestTimestamp = 123;
-static const int64_t kTestNtpTimeMs = 456;
+constexpr uint32_t kTestTimestamp = 123;
+constexpr int64_t kTestNtpTimeMs = 456;
+constexpr uint32_t kTimestampIncrementPerFrame = 3000;
+
+} // 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)
- : encoded_frame_(frame), encode_complete_(false) {}
+ : encoded_frame_(frame),
+ codec_specific_info_(codec_specific_info),
+ encode_complete_(false) {}
Result OnEncodedImage(const EncodedImage& encoded_frame_,
const CodecSpecificInfo* codec_specific_info,
@@ -54,6 +60,7 @@ class Vp8UnitTestEncodeCompleteCallback : public webrtc::EncodedImageCallback {
private:
EncodedImage* const encoded_frame_;
+ CodecSpecificInfo* const codec_specific_info_;
std::unique_ptr<uint8_t[]> frame_buffer_;
bool encode_complete_;
};
@@ -77,6 +84,9 @@ Vp8UnitTestEncodeCompleteCallback::OnEncodedImage(
encoded_frame_->_frameType = encoded_frame._frameType;
encoded_frame_->_completeFrame = encoded_frame._completeFrame;
encoded_frame_->qp_ = encoded_frame.qp_;
+ codec_specific_info_->codecType = codec_specific_info->codecType;
+ // Skip |codec_name|, to avoid allocating.
+ codec_specific_info_->codecSpecific = codec_specific_info->codecSpecific;
encode_complete_ = true;
return Result(Result::OK, 0);
}
@@ -135,9 +145,9 @@ class TestVp8Impl : public ::testing::Test {
virtual void SetUp() {
encoder_.reset(VP8Encoder::Create());
decoder_.reset(VP8Decoder::Create());
- memset(&codec_inst_, 0, sizeof(codec_inst_));
- encode_complete_callback_.reset(
- new Vp8UnitTestEncodeCompleteCallback(&encoded_frame_, 0, NULL));
+ memset(&codec_settings_, 0, sizeof(codec_settings_));
+ encode_complete_callback_.reset(new Vp8UnitTestEncodeCompleteCallback(
+ &encoded_frame_, &codec_specific_info_, 0, nullptr));
decode_complete_callback_.reset(
new Vp8UnitTestDecodeCompleteCallback(&decoded_frame_, &decoded_qp_));
encoder_->RegisterEncodeCompleteCallback(encode_complete_callback_.get());
@@ -145,18 +155,18 @@ class TestVp8Impl : public ::testing::Test {
// 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_ != NULL);
+ ASSERT_TRUE(source_file_ != nullptr);
rtc::scoped_refptr<VideoFrameBuffer> compact_buffer(
test::ReadI420Buffer(kWidth, kHeight, source_file_));
ASSERT_TRUE(compact_buffer);
- codec_inst_.width = kWidth;
- codec_inst_.height = kHeight;
+ codec_settings_.width = kWidth;
+ codec_settings_.height = kHeight;
const int kFramerate = 30;
- codec_inst_.maxFramerate = kFramerate;
+ codec_settings_.maxFramerate = kFramerate;
// Setting aligned stride values.
int stride_uv;
int stride_y;
- Calc16ByteAlignedStride(codec_inst_.width, &stride_y, &stride_uv);
+ Calc16ByteAlignedStride(codec_settings_.width, &stride_y, &stride_uv);
EXPECT_EQ(stride_y, 176);
EXPECT_EQ(stride_uv, 96);
@@ -172,16 +182,16 @@ class TestVp8Impl : public ::testing::Test {
}
void SetUpEncodeDecode() {
- codec_inst_.startBitrate = 300;
- codec_inst_.maxBitrate = 4000;
- codec_inst_.qpMax = 56;
- codec_inst_.VP8()->denoisingOn = true;
- codec_inst_.VP8()->tl_factory = &tl_factory_;
- codec_inst_.VP8()->numberOfTemporalLayers = 1;
+ codec_settings_.startBitrate = 300;
+ codec_settings_.maxBitrate = 4000;
+ codec_settings_.qpMax = 56;
+ codec_settings_.VP8()->denoisingOn = true;
+ codec_settings_.VP8()->tl_factory = &tl_factory_;
+ codec_settings_.VP8()->numberOfTemporalLayers = 1;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->InitEncode(&codec_inst_, 1, 1440));
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->InitDecode(&codec_inst_, 1));
+ encoder_->InitEncode(&codec_settings_, 1, 1440));
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->InitDecode(&codec_settings_, 1));
}
size_t WaitForEncodedFrame() const {
@@ -205,6 +215,15 @@ class TestVp8Impl : public ::testing::Test {
return 0;
}
+ void ExpectFrameWith(int16_t picture_id,
+ int tl0_pic_idx,
+ uint8_t temporal_idx) {
+ ASSERT_TRUE(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;
@@ -216,25 +235,26 @@ class TestVp8Impl : public ::testing::Test {
std::unique_ptr<VideoEncoder> encoder_;
std::unique_ptr<VideoDecoder> decoder_;
EncodedImage encoded_frame_;
+ CodecSpecificInfo codec_specific_info_;
rtc::Optional<VideoFrame> decoded_frame_;
rtc::Optional<uint8_t> decoded_qp_;
- VideoCodec codec_inst_;
+ VideoCodec codec_settings_;
TemporalLayersFactory tl_factory_;
};
TEST_F(TestVp8Impl, EncoderParameterTest) {
- strncpy(codec_inst_.plName, "VP8", 31);
- codec_inst_.plType = 126;
- codec_inst_.maxBitrate = 0;
- codec_inst_.minBitrate = 0;
- codec_inst_.width = 1440;
- codec_inst_.height = 1080;
- codec_inst_.maxFramerate = 30;
- codec_inst_.startBitrate = 300;
- codec_inst_.qpMax = 56;
- codec_inst_.VP8()->complexity = kComplexityNormal;
- codec_inst_.VP8()->numberOfTemporalLayers = 1;
- codec_inst_.VP8()->tl_factory = &tl_factory_;
+ 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;
@@ -242,14 +262,15 @@ TEST_F(TestVp8Impl, EncoderParameterTest) {
bitrate_allocation.SetBitrate(0, 0, bit_rate * 1000);
EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED,
encoder_->SetRateAllocation(bitrate_allocation,
- codec_inst_.maxFramerate));
+ codec_settings_.maxFramerate));
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->InitEncode(&codec_inst_, 1, 1440));
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder_->InitEncode(&codec_settings_, 1, 1440));
// Decoder parameter tests.
// Calls before InitDecode().
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release());
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->InitDecode(&codec_inst_, 1));
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->InitDecode(&codec_settings_, 1));
}
TEST_F(TestVp8Impl, DecodedQpEqualsEncodedQp) {
@@ -274,13 +295,13 @@ TEST_F(TestVp8Impl, DecodedQpEqualsEncodedQp) {
#endif
TEST_F(TestVp8Impl, MAYBE_AlignedStrideEncodeDecode) {
SetUpEncodeDecode();
- encoder_->Encode(*input_frame_, NULL, NULL);
+ encoder_->Encode(*input_frame_, nullptr, nullptr);
EXPECT_GT(WaitForEncodedFrame(), 0u);
// 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, NULL));
+ decoder_->Decode(encoded_frame_, false, nullptr));
EXPECT_GT(WaitForDecodedFrame(), 0u);
ASSERT_TRUE(decoded_frame_);
// Compute PSNR on all planes (faster than SSIM).
@@ -296,23 +317,99 @@ TEST_F(TestVp8Impl, MAYBE_AlignedStrideEncodeDecode) {
#endif
TEST_F(TestVp8Impl, MAYBE_DecodeWithACompleteKeyFrame) {
SetUpEncodeDecode();
- encoder_->Encode(*input_frame_, NULL, NULL);
+ encoder_->Encode(*input_frame_, nullptr, nullptr);
EXPECT_GT(WaitForEncodedFrame(), 0u);
// Setting complete to false -> should return an error.
encoded_frame_._completeFrame = false;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
- decoder_->Decode(encoded_frame_, false, NULL));
+ decoder_->Decode(encoded_frame_, false, nullptr));
// Setting complete back to true. Forcing a delta frame.
encoded_frame_._frameType = kVideoFrameDelta;
encoded_frame_._completeFrame = true;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
- decoder_->Decode(encoded_frame_, false, NULL));
+ decoder_->Decode(encoded_frame_, false, nullptr));
// Now setting a key frame.
encoded_frame_._frameType = kVideoFrameKey;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- decoder_->Decode(encoded_frame_, false, NULL));
+ decoder_->Decode(encoded_frame_, false, nullptr));
ASSERT_TRUE(decoded_frame_);
EXPECT_GT(I420PSNR(input_frame_.get(), &*decoded_frame_), 36);
}
+TEST_F(TestVp8Impl, EncoderRetainsRtpStateAfterRelease) {
+ SetUpEncodeDecode();
+ // Override default settings.
+ codec_settings_.VP8()->numberOfTemporalLayers = 2;
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder_->InitEncode(&codec_settings_, 1, 1440));
+
+ // Temporal layer 0.
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder_->Encode(*input_frame_, nullptr, nullptr));
+ ASSERT_TRUE(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;
+
+ // Temporal layer 1.
+ input_frame_->set_timestamp(input_frame_->timestamp() +
+ kTimestampIncrementPerFrame);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder_->Encode(*input_frame_, nullptr, nullptr));
+ ExpectFrameWith((picture_id + 1) % (1 << 15), tl0_pic_idx, 1);
+
+ // Temporal layer 0.
+ input_frame_->set_timestamp(input_frame_->timestamp() +
+ kTimestampIncrementPerFrame);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder_->Encode(*input_frame_, nullptr, nullptr));
+ ExpectFrameWith((picture_id + 2) % (1 << 15), (tl0_pic_idx + 1) % (1 << 8),
+ 0);
+
+ // Temporal layer 1.
+ input_frame_->set_timestamp(input_frame_->timestamp() +
+ kTimestampIncrementPerFrame);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder_->Encode(*input_frame_, nullptr, nullptr));
+ ExpectFrameWith((picture_id + 3) % (1 << 15), (tl0_pic_idx + 1) % (1 << 8),
+ 1);
+
+ // Reinit.
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder_->InitEncode(&codec_settings_, 1, 1440));
+
+ // Temporal layer 0.
+ input_frame_->set_timestamp(input_frame_->timestamp() +
+ kTimestampIncrementPerFrame);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder_->Encode(*input_frame_, nullptr, nullptr));
+ ExpectFrameWith((picture_id + 4) % (1 << 15), (tl0_pic_idx + 2) % (1 << 8),
+ 0);
+
+ // Temporal layer 1.
+ input_frame_->set_timestamp(input_frame_->timestamp() +
+ kTimestampIncrementPerFrame);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder_->Encode(*input_frame_, nullptr, nullptr));
+ ExpectFrameWith((picture_id + 5) % (1 << 15), (tl0_pic_idx + 2) % (1 << 8),
+ 1);
+
+ // Temporal layer 0.
+ input_frame_->set_timestamp(input_frame_->timestamp() +
+ kTimestampIncrementPerFrame);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder_->Encode(*input_frame_, nullptr, nullptr));
+ ExpectFrameWith((picture_id + 6) % (1 << 15), (tl0_pic_idx + 3) % (1 << 8),
+ 0);
+
+ // Temporal layer 1.
+ input_frame_->set_timestamp(input_frame_->timestamp() +
+ kTimestampIncrementPerFrame);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder_->Encode(*input_frame_, nullptr, nullptr));
+ ExpectFrameWith((picture_id + 7) % (1 << 15), (tl0_pic_idx + 3) % (1 << 8),
+ 1);
+}
+
} // namespace webrtc
« no previous file with comments | « webrtc/modules/video_coding/codecs/vp8/temporal_layers.h ('k') | webrtc/modules/video_coding/codecs/vp8/vp8_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698