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

Side by Side 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: holmer comments 1: add unit tests for tl0_pic_idx. 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 unified diff | Download patch
OLDNEW
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
11 #include <stdio.h> 11 #include <stdio.h>
12 12
13 #include <memory> 13 #include <memory>
14 14
15 #include "webrtc/api/video/i420_buffer.h" 15 #include "webrtc/api/video/i420_buffer.h"
16 #include "webrtc/base/checks.h" 16 #include "webrtc/base/checks.h"
17 #include "webrtc/base/optional.h" 17 #include "webrtc/base/optional.h"
18 #include "webrtc/base/timeutils.h" 18 #include "webrtc/base/timeutils.h"
19 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" 19 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
20 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" 20 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
21 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" 21 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h"
22 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
22 #include "webrtc/test/frame_utils.h" 23 #include "webrtc/test/frame_utils.h"
23 #include "webrtc/test/gtest.h" 24 #include "webrtc/test/gtest.h"
24 #include "webrtc/test/testsupport/fileutils.h" 25 #include "webrtc/test/testsupport/fileutils.h"
25 26
26 namespace webrtc { 27 namespace webrtc {
27 28
28 namespace { 29 namespace {
29 void Calc16ByteAlignedStride(int width, int* stride_y, int* stride_uv) { 30 void Calc16ByteAlignedStride(int width, int* stride_y, int* stride_uv) {
30 *stride_y = 16 * ((width + 15) / 16); 31 *stride_y = 16 * ((width + 15) / 16);
31 *stride_uv = 16 * ((width + 31) / 32); 32 *stride_uv = 16 * ((width + 31) / 32);
32 } 33 }
33 34
34 } // Anonymous namespace 35 } // Anonymous namespace
35 36
36 enum { kMaxWaitEncTimeMs = 100 }; 37 enum { kMaxWaitEncTimeMs = 100 };
37 enum { kMaxWaitDecTimeMs = 25 }; 38 enum { kMaxWaitDecTimeMs = 25 };
38 39
39 static const uint32_t kTestTimestamp = 123; 40 static const uint32_t kTestTimestamp = 123;
40 static const int64_t kTestNtpTimeMs = 456; 41 static const int64_t kTestNtpTimeMs = 456;
41 42
42 // TODO(mikhal): Replace these with mocks. 43 // TODO(mikhal): Replace these with mocks.
43 class Vp8UnitTestEncodeCompleteCallback : public webrtc::EncodedImageCallback { 44 class Vp8UnitTestEncodeCompleteCallback : public webrtc::EncodedImageCallback {
44 public: 45 public:
45 Vp8UnitTestEncodeCompleteCallback(EncodedImage* frame, 46 Vp8UnitTestEncodeCompleteCallback(EncodedImage* frame,
47 CodecSpecificInfo* codec_specific_info,
46 unsigned int decoderSpecificSize, 48 unsigned int decoderSpecificSize,
47 void* decoderSpecificInfo) 49 void* decoderSpecificInfo)
48 : encoded_frame_(frame), encode_complete_(false) {} 50 : encoded_frame_(frame),
51 codec_specific_info_(codec_specific_info),
52 encode_complete_(false) {}
49 53
50 Result OnEncodedImage(const EncodedImage& encoded_frame_, 54 Result OnEncodedImage(const EncodedImage& encoded_frame_,
51 const CodecSpecificInfo* codec_specific_info, 55 const CodecSpecificInfo* codec_specific_info,
52 const RTPFragmentationHeader* fragmentation) override; 56 const RTPFragmentationHeader* fragmentation) override;
53 bool EncodeComplete(); 57 bool EncodeComplete();
54 58
55 private: 59 private:
56 EncodedImage* const encoded_frame_; 60 EncodedImage* const encoded_frame_;
61 CodecSpecificInfo* const codec_specific_info_;
57 std::unique_ptr<uint8_t[]> frame_buffer_; 62 std::unique_ptr<uint8_t[]> frame_buffer_;
58 bool encode_complete_; 63 bool encode_complete_;
59 }; 64 };
60 65
61 webrtc::EncodedImageCallback::Result 66 webrtc::EncodedImageCallback::Result
62 Vp8UnitTestEncodeCompleteCallback::OnEncodedImage( 67 Vp8UnitTestEncodeCompleteCallback::OnEncodedImage(
63 const EncodedImage& encoded_frame, 68 const EncodedImage& encoded_frame,
64 const CodecSpecificInfo* codec_specific_info, 69 const CodecSpecificInfo* codec_specific_info,
65 const RTPFragmentationHeader* fragmentation) { 70 const RTPFragmentationHeader* fragmentation) {
66 if (encoded_frame_->_size < encoded_frame._length) { 71 if (encoded_frame_->_size < encoded_frame._length) {
67 delete[] encoded_frame_->_buffer; 72 delete[] encoded_frame_->_buffer;
68 frame_buffer_.reset(new uint8_t[encoded_frame._length]); 73 frame_buffer_.reset(new uint8_t[encoded_frame._length]);
69 encoded_frame_->_buffer = frame_buffer_.get(); 74 encoded_frame_->_buffer = frame_buffer_.get();
70 encoded_frame_->_size = encoded_frame._length; 75 encoded_frame_->_size = encoded_frame._length;
71 } 76 }
72 memcpy(encoded_frame_->_buffer, encoded_frame._buffer, encoded_frame._length); 77 memcpy(encoded_frame_->_buffer, encoded_frame._buffer, encoded_frame._length);
73 encoded_frame_->_length = encoded_frame._length; 78 encoded_frame_->_length = encoded_frame._length;
74 encoded_frame_->_encodedWidth = encoded_frame._encodedWidth; 79 encoded_frame_->_encodedWidth = encoded_frame._encodedWidth;
75 encoded_frame_->_encodedHeight = encoded_frame._encodedHeight; 80 encoded_frame_->_encodedHeight = encoded_frame._encodedHeight;
76 encoded_frame_->_timeStamp = encoded_frame._timeStamp; 81 encoded_frame_->_timeStamp = encoded_frame._timeStamp;
77 encoded_frame_->_frameType = encoded_frame._frameType; 82 encoded_frame_->_frameType = encoded_frame._frameType;
78 encoded_frame_->_completeFrame = encoded_frame._completeFrame; 83 encoded_frame_->_completeFrame = encoded_frame._completeFrame;
79 encoded_frame_->qp_ = encoded_frame.qp_; 84 encoded_frame_->qp_ = encoded_frame.qp_;
85 codec_specific_info_->codecType = codec_specific_info->codecType;
86 // Skip |codec_name|, to avoid allocating.
87 codec_specific_info_->codecSpecific = codec_specific_info->codecSpecific;
80 encode_complete_ = true; 88 encode_complete_ = true;
81 return Result(Result::OK, 0); 89 return Result(Result::OK, 0);
82 } 90 }
83 91
84 bool Vp8UnitTestEncodeCompleteCallback::EncodeComplete() { 92 bool Vp8UnitTestEncodeCompleteCallback::EncodeComplete() {
85 if (encode_complete_) { 93 if (encode_complete_) {
86 encode_complete_ = false; 94 encode_complete_ = false;
87 return true; 95 return true;
88 } 96 }
89 return false; 97 return false;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 *decoded_qp_ = qp; 137 *decoded_qp_ = qp;
130 decode_complete = true; 138 decode_complete = true;
131 } 139 }
132 140
133 class TestVp8Impl : public ::testing::Test { 141 class TestVp8Impl : public ::testing::Test {
134 protected: 142 protected:
135 virtual void SetUp() { 143 virtual void SetUp() {
136 encoder_.reset(VP8Encoder::Create()); 144 encoder_.reset(VP8Encoder::Create());
137 decoder_.reset(VP8Decoder::Create()); 145 decoder_.reset(VP8Decoder::Create());
138 memset(&codec_inst_, 0, sizeof(codec_inst_)); 146 memset(&codec_inst_, 0, sizeof(codec_inst_));
139 encode_complete_callback_.reset( 147 encode_complete_callback_.reset(new Vp8UnitTestEncodeCompleteCallback(
140 new Vp8UnitTestEncodeCompleteCallback(&encoded_frame_, 0, NULL)); 148 &encoded_frame_, &codec_specific_info_, 0, nullptr));
141 decode_complete_callback_.reset( 149 decode_complete_callback_.reset(
142 new Vp8UnitTestDecodeCompleteCallback(&decoded_frame_, &decoded_qp_)); 150 new Vp8UnitTestDecodeCompleteCallback(&decoded_frame_, &decoded_qp_));
143 encoder_->RegisterEncodeCompleteCallback(encode_complete_callback_.get()); 151 encoder_->RegisterEncodeCompleteCallback(encode_complete_callback_.get());
144 decoder_->RegisterDecodeCompleteCallback(decode_complete_callback_.get()); 152 decoder_->RegisterDecodeCompleteCallback(decode_complete_callback_.get());
145 // Using a QCIF image (aligned stride (u,v planes) > width). 153 // Using a QCIF image (aligned stride (u,v planes) > width).
146 // Processing only one frame. 154 // Processing only one frame.
147 source_file_ = fopen(test::ResourcePath("paris_qcif", "yuv").c_str(), "rb"); 155 source_file_ = fopen(test::ResourcePath("paris_qcif", "yuv").c_str(), "rb");
148 ASSERT_TRUE(source_file_ != NULL); 156 ASSERT_TRUE(source_file_ != nullptr);
149 rtc::scoped_refptr<VideoFrameBuffer> compact_buffer( 157 rtc::scoped_refptr<VideoFrameBuffer> compact_buffer(
150 test::ReadI420Buffer(kWidth, kHeight, source_file_)); 158 test::ReadI420Buffer(kWidth, kHeight, source_file_));
151 ASSERT_TRUE(compact_buffer); 159 ASSERT_TRUE(compact_buffer);
152 codec_inst_.width = kWidth; 160 codec_inst_.width = kWidth;
153 codec_inst_.height = kHeight; 161 codec_inst_.height = kHeight;
154 const int kFramerate = 30; 162 const int kFramerate = 30;
155 codec_inst_.maxFramerate = kFramerate; 163 codec_inst_.maxFramerate = kFramerate;
156 // Setting aligned stride values. 164 // Setting aligned stride values.
157 int stride_uv; 165 int stride_uv;
158 int stride_y; 166 int stride_y;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 const int kHeight = 144; 217 const int kHeight = 144;
210 218
211 std::unique_ptr<Vp8UnitTestEncodeCompleteCallback> encode_complete_callback_; 219 std::unique_ptr<Vp8UnitTestEncodeCompleteCallback> encode_complete_callback_;
212 std::unique_ptr<Vp8UnitTestDecodeCompleteCallback> decode_complete_callback_; 220 std::unique_ptr<Vp8UnitTestDecodeCompleteCallback> decode_complete_callback_;
213 std::unique_ptr<uint8_t[]> source_buffer_; 221 std::unique_ptr<uint8_t[]> source_buffer_;
214 FILE* source_file_; 222 FILE* source_file_;
215 std::unique_ptr<VideoFrame> input_frame_; 223 std::unique_ptr<VideoFrame> input_frame_;
216 std::unique_ptr<VideoEncoder> encoder_; 224 std::unique_ptr<VideoEncoder> encoder_;
217 std::unique_ptr<VideoDecoder> decoder_; 225 std::unique_ptr<VideoDecoder> decoder_;
218 EncodedImage encoded_frame_; 226 EncodedImage encoded_frame_;
227 CodecSpecificInfo codec_specific_info_;
219 rtc::Optional<VideoFrame> decoded_frame_; 228 rtc::Optional<VideoFrame> decoded_frame_;
220 rtc::Optional<uint8_t> decoded_qp_; 229 rtc::Optional<uint8_t> decoded_qp_;
221 VideoCodec codec_inst_; 230 VideoCodec codec_inst_;
222 TemporalLayersFactory tl_factory_; 231 TemporalLayersFactory tl_factory_;
223 }; 232 };
224 233
225 TEST_F(TestVp8Impl, EncoderParameterTest) { 234 TEST_F(TestVp8Impl, EncoderParameterTest) {
226 strncpy(codec_inst_.plName, "VP8", 31); 235 strncpy(codec_inst_.plName, "VP8", 31);
227 codec_inst_.plType = 126; 236 codec_inst_.plType = 126;
228 codec_inst_.maxBitrate = 0; 237 codec_inst_.maxBitrate = 0;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 EXPECT_EQ(encoded_frame_.qp_, *decoded_qp_); 276 EXPECT_EQ(encoded_frame_.qp_, *decoded_qp_);
268 } 277 }
269 278
270 #if defined(WEBRTC_ANDROID) 279 #if defined(WEBRTC_ANDROID)
271 #define MAYBE_AlignedStrideEncodeDecode DISABLED_AlignedStrideEncodeDecode 280 #define MAYBE_AlignedStrideEncodeDecode DISABLED_AlignedStrideEncodeDecode
272 #else 281 #else
273 #define MAYBE_AlignedStrideEncodeDecode AlignedStrideEncodeDecode 282 #define MAYBE_AlignedStrideEncodeDecode AlignedStrideEncodeDecode
274 #endif 283 #endif
275 TEST_F(TestVp8Impl, MAYBE_AlignedStrideEncodeDecode) { 284 TEST_F(TestVp8Impl, MAYBE_AlignedStrideEncodeDecode) {
276 SetUpEncodeDecode(); 285 SetUpEncodeDecode();
277 encoder_->Encode(*input_frame_, NULL, NULL); 286 encoder_->Encode(*input_frame_, nullptr, nullptr);
278 EXPECT_GT(WaitForEncodedFrame(), 0u); 287 EXPECT_GT(WaitForEncodedFrame(), 0u);
279 // First frame should be a key frame. 288 // First frame should be a key frame.
280 encoded_frame_._frameType = kVideoFrameKey; 289 encoded_frame_._frameType = kVideoFrameKey;
281 encoded_frame_.ntp_time_ms_ = kTestNtpTimeMs; 290 encoded_frame_.ntp_time_ms_ = kTestNtpTimeMs;
282 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, 291 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
283 decoder_->Decode(encoded_frame_, false, NULL)); 292 decoder_->Decode(encoded_frame_, false, nullptr));
284 EXPECT_GT(WaitForDecodedFrame(), 0u); 293 EXPECT_GT(WaitForDecodedFrame(), 0u);
285 ASSERT_TRUE(decoded_frame_); 294 ASSERT_TRUE(decoded_frame_);
286 // Compute PSNR on all planes (faster than SSIM). 295 // Compute PSNR on all planes (faster than SSIM).
287 EXPECT_GT(I420PSNR(input_frame_.get(), &*decoded_frame_), 36); 296 EXPECT_GT(I420PSNR(input_frame_.get(), &*decoded_frame_), 36);
288 EXPECT_EQ(kTestTimestamp, decoded_frame_->timestamp()); 297 EXPECT_EQ(kTestTimestamp, decoded_frame_->timestamp());
289 EXPECT_EQ(kTestNtpTimeMs, decoded_frame_->ntp_time_ms()); 298 EXPECT_EQ(kTestNtpTimeMs, decoded_frame_->ntp_time_ms());
290 } 299 }
291 300
292 #if defined(WEBRTC_ANDROID) 301 #if defined(WEBRTC_ANDROID)
293 #define MAYBE_DecodeWithACompleteKeyFrame DISABLED_DecodeWithACompleteKeyFrame 302 #define MAYBE_DecodeWithACompleteKeyFrame DISABLED_DecodeWithACompleteKeyFrame
294 #else 303 #else
295 #define MAYBE_DecodeWithACompleteKeyFrame DecodeWithACompleteKeyFrame 304 #define MAYBE_DecodeWithACompleteKeyFrame DecodeWithACompleteKeyFrame
296 #endif 305 #endif
297 TEST_F(TestVp8Impl, MAYBE_DecodeWithACompleteKeyFrame) { 306 TEST_F(TestVp8Impl, MAYBE_DecodeWithACompleteKeyFrame) {
298 SetUpEncodeDecode(); 307 SetUpEncodeDecode();
299 encoder_->Encode(*input_frame_, NULL, NULL); 308 encoder_->Encode(*input_frame_, nullptr, nullptr);
300 EXPECT_GT(WaitForEncodedFrame(), 0u); 309 EXPECT_GT(WaitForEncodedFrame(), 0u);
301 // Setting complete to false -> should return an error. 310 // Setting complete to false -> should return an error.
302 encoded_frame_._completeFrame = false; 311 encoded_frame_._completeFrame = false;
303 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, 312 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
304 decoder_->Decode(encoded_frame_, false, NULL)); 313 decoder_->Decode(encoded_frame_, false, nullptr));
305 // Setting complete back to true. Forcing a delta frame. 314 // Setting complete back to true. Forcing a delta frame.
306 encoded_frame_._frameType = kVideoFrameDelta; 315 encoded_frame_._frameType = kVideoFrameDelta;
307 encoded_frame_._completeFrame = true; 316 encoded_frame_._completeFrame = true;
308 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, 317 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
309 decoder_->Decode(encoded_frame_, false, NULL)); 318 decoder_->Decode(encoded_frame_, false, nullptr));
310 // Now setting a key frame. 319 // Now setting a key frame.
311 encoded_frame_._frameType = kVideoFrameKey; 320 encoded_frame_._frameType = kVideoFrameKey;
312 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, 321 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
313 decoder_->Decode(encoded_frame_, false, NULL)); 322 decoder_->Decode(encoded_frame_, false, nullptr));
314 ASSERT_TRUE(decoded_frame_); 323 ASSERT_TRUE(decoded_frame_);
315 EXPECT_GT(I420PSNR(input_frame_.get(), &*decoded_frame_), 36); 324 EXPECT_GT(I420PSNR(input_frame_.get(), &*decoded_frame_), 36);
316 } 325 }
317 326
327 TEST_F(TestVp8Impl, EncoderRetainsRtpStateAfterRelease) {
328 SetUpEncodeDecode();
329 // Override default settings.
330 codec_inst_.VP8()->numberOfTemporalLayers = 2;
331 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->InitEncode(&codec_inst_, 1, 1440));
332
333 // Temporal layer 0.
334 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
335 encoder_->Encode(*input_frame_, nullptr, nullptr));
336 ASSERT_TRUE(WaitForEncodedFrame());
337 EXPECT_EQ(0, codec_specific_info_.codecSpecific.VP8.temporalIdx);
338 uint16_t picture_id = codec_specific_info_.codecSpecific.VP8.pictureId;
339 uint8_t tl0_pic_idx = codec_specific_info_.codecSpecific.VP8.tl0PicIdx;
340
341 // Temporal layer 1.
342 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
343 encoder_->Encode(*input_frame_, nullptr, nullptr));
åsapersson 2017/04/27 12:09:39 increase timestamp for new frames (since it is use
344 ASSERT_TRUE(WaitForEncodedFrame());
345 EXPECT_EQ(1, codec_specific_info_.codecSpecific.VP8.temporalIdx);
346 EXPECT_EQ((picture_id + 1) % (1 << 15),
347 codec_specific_info_.codecSpecific.VP8.pictureId);
348 EXPECT_EQ(tl0_pic_idx, codec_specific_info_.codecSpecific.VP8.tl0PicIdx);
349
350 // Reinit.
351 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
352 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->InitEncode(&codec_inst_, 1, 1440));
353
354 // Temporal layer 0.
355 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
356 encoder_->Encode(*input_frame_, nullptr, nullptr));
357 ASSERT_TRUE(WaitForEncodedFrame());
358 EXPECT_EQ(0, codec_specific_info_.codecSpecific.VP8.temporalIdx);
359 EXPECT_EQ((picture_id + 2) % (1 << 15),
360 codec_specific_info_.codecSpecific.VP8.pictureId);
361 EXPECT_EQ((tl0_pic_idx + 1) % (1 << 8),
362 codec_specific_info_.codecSpecific.VP8.tl0PicIdx);
363
364 // Temporal layer 1.
365 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
366 encoder_->Encode(*input_frame_, nullptr, nullptr));
367 ASSERT_TRUE(WaitForEncodedFrame());
368 EXPECT_EQ(1, codec_specific_info_.codecSpecific.VP8.temporalIdx);
369 EXPECT_EQ((picture_id + 3) % (1 << 15),
370 codec_specific_info_.codecSpecific.VP8.pictureId);
371 EXPECT_EQ((tl0_pic_idx + 1) % (1 << 8),
372 codec_specific_info_.codecSpecific.VP8.tl0PicIdx);
373 }
374
318 } // namespace webrtc 375 } // namespace webrtc
OLDNEW
« 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