2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "webrtc/modules/video_coding/codecs/test_framework/unit_test.h"
18 #include "webrtc/modules/video_coding/codecs/test_framework/video_source.h"
19 #include "webrtc/system_wrappers/interface/tick_util.h"
20 #include "webrtc/test/testsupport/fileutils.h"
22 using namespace webrtc;
26 CodecTest("UnitTest", "Unit test"),
33 _refEncFrameLength(0),
36 _encodeCompleteCallback(NULL),
37 _decodeCompleteCallback(NULL)
41 UnitTest::UnitTest(std::string name, std::string description)
43 CodecTest(name, description),
50 _refEncFrameLength(0),
53 _encodeCompleteCallback(NULL),
54 _decodeCompleteCallback(NULL)
60 if (_encodeCompleteCallback) {
61 delete _encodeCompleteCallback;
64 if (_decodeCompleteCallback) {
65 delete _decodeCompleteCallback;
77 delete [] _refDecFrame;
81 delete [] _sourceBuffer;
89 delete [] _refEncFrame;
94 UnitTestEncodeCompleteCallback::Encoded(EncodedImage& encodedImage,
95 const webrtc::CodecSpecificInfo* codecSpecificInfo,
96 const webrtc::RTPFragmentationHeader*
99 _encodedVideoBuffer->VerifyAndAllocate(encodedImage._size);
100 _encodedVideoBuffer->CopyFrame(encodedImage._size, encodedImage._buffer);
101 _encodedVideoBuffer->SetLength(encodedImage._length);
102 // TODO(mikhal): Update frame type API.
103 // _encodedVideoBuffer->SetFrameType(encodedImage._frameType);
104 _encodedVideoBuffer->SetWidth(
105 (uint16_t)encodedImage._encodedWidth);
106 _encodedVideoBuffer->SetHeight(
107 (uint16_t)encodedImage._encodedHeight);
108 _encodedVideoBuffer->SetTimeStamp(encodedImage._timeStamp);
109 _encodeComplete = true;
110 _encodedFrameType = encodedImage._frameType;
114 int32_t UnitTestDecodeCompleteCallback::Decoded(I420VideoFrame& image)
116 _decodedVideoBuffer->CopyFrame(image);
117 _decodeComplete = true;
122 UnitTestEncodeCompleteCallback::EncodeComplete()
126 _encodeComplete = false;
133 UnitTestEncodeCompleteCallback::EncodedFrameType() const
135 return _encodedFrameType;
139 UnitTestDecodeCompleteCallback::DecodeComplete()
143 _decodeComplete = false;
150 UnitTest::WaitForEncodedFrame() const
152 int64_t startTime = TickTime::MillisecondTimestamp();
153 while (TickTime::MillisecondTimestamp() - startTime < kMaxWaitEncTimeMs)
155 if (_encodeCompleteCallback->EncodeComplete())
157 return _encodedVideoBuffer.Length();
164 UnitTest::WaitForDecodedFrame() const
166 int64_t startTime = TickTime::MillisecondTimestamp();
167 while (TickTime::MillisecondTimestamp() - startTime < kMaxWaitDecTimeMs)
169 if (_decodeCompleteCallback->DecodeComplete())
171 return webrtc::CalcBufferSize(kI420, _decodedVideoBuffer.width(),
172 _decodedVideoBuffer.height());
179 UnitTest::CodecSpecific_SetBitrate(uint32_t bitRate,
180 uint32_t /* frameRate */)
182 return _encoder->SetRates(bitRate, _inst.maxFramerate);
188 // Use _sourceFile as a check to prevent multiple Setup() calls.
189 if (_sourceFile != NULL)
194 if (_encodeCompleteCallback == NULL)
196 _encodeCompleteCallback =
197 new UnitTestEncodeCompleteCallback(&_encodedVideoBuffer);
199 if (_decodeCompleteCallback == NULL)
201 _decodeCompleteCallback =
202 new UnitTestDecodeCompleteCallback(&_decodedVideoBuffer);
205 _encoder->RegisterEncodeCompleteCallback(_encodeCompleteCallback);
206 _decoder->RegisterDecodeCompleteCallback(_decodeCompleteCallback);
208 _source = new VideoSource(webrtc::test::ProjectRootPath() +
209 "resources/foreman_cif.yuv", kCIF);
211 _lengthSourceFrame = _source->GetFrameLength();
212 _refFrame = new unsigned char[_lengthSourceFrame];
213 _refDecFrame = new unsigned char[_lengthSourceFrame];
214 _sourceBuffer = new unsigned char [_lengthSourceFrame];
215 _sourceFile = fopen(_source->GetFileName().c_str(), "rb");
216 ASSERT_TRUE(_sourceFile != NULL);
218 _inst.maxFramerate = _source->GetFrameRate();
220 _inst.startBitrate = 300;
221 _inst.maxBitrate = 4000;
222 _inst.width = _source->GetWidth();
223 _inst.height = _source->GetHeight();
225 _inst.codecSpecific.VP8.denoisingOn = true;
228 ASSERT_TRUE(fread(_refFrame, 1, _lengthSourceFrame, _sourceFile)
229 == _lengthSourceFrame);
230 int size_y = _inst.width * _inst.height;
231 int size_uv = ((_inst.width + 1) / 2) * ((_inst.height + 1) / 2);
232 _inputVideoBuffer.CreateFrame(size_y, _refFrame,
233 size_uv, _refFrame + size_y,
234 size_uv, _refFrame + size_y + size_uv,
235 _inst.width, _inst.height,
237 (_inst.width + 1) / 2, (_inst.width + 1) / 2);
240 // Get a reference encoded frame.
241 _encodedVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
243 // Ensures our initial parameters are valid.
244 EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
245 _encoder->Encode(_inputVideoBuffer, NULL, NULL);
246 _refEncFrameLength = WaitForEncodedFrame();
247 ASSERT_TRUE(_refEncFrameLength > 0);
248 _refEncFrame = new unsigned char[_refEncFrameLength];
249 memcpy(_refEncFrame, _encodedVideoBuffer.Buffer(), _refEncFrameLength);
251 // Get a reference decoded frame.
252 _decodedVideoBuffer.CreateEmptyFrame(_inst.width, _inst.height, _inst.width,
253 (_inst.width + 1) / 2,
254 (_inst.width + 1) / 2);
255 EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
256 ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
258 unsigned int frameLength = 0;
260 _inputVideoBuffer.CreateEmptyFrame(_inst.width, _inst.height, _inst.width,
261 (_inst.width + 1) / 2,
262 (_inst.width + 1) / 2);
263 while (frameLength == 0)
265 EncodedImage encodedImage;
268 // Insert yet another frame.
269 ASSERT_TRUE(fread(_refFrame, 1, _lengthSourceFrame,
270 _sourceFile) == _lengthSourceFrame);
271 EXPECT_EQ(0, ConvertToI420(kI420, _refFrame, 0, 0, _width, _height,
272 0, kRotateNone, &_inputVideoBuffer));
273 _encoder->Encode(_inputVideoBuffer, NULL, NULL);
274 ASSERT_TRUE(WaitForEncodedFrame() > 0);
276 // The first frame is always a key frame.
277 encodedImage._frameType = kKeyFrame;
280 VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
281 ASSERT_TRUE(_decoder->Decode(encodedImage, 0, NULL)
282 == WEBRTC_VIDEO_CODEC_OK);
283 frameLength = WaitForDecodedFrame();
284 _encodedVideoBuffer.SetLength(0);
288 EXPECT_TRUE(frameLength == _lengthSourceFrame);
289 ExtractBuffer(_decodedVideoBuffer, _lengthSourceFrame, _refDecFrame);
295 // Use _sourceFile as a check to prevent multiple Teardown() calls.
296 if (_sourceFile == NULL)
308 delete [] _refEncFrame;
310 delete [] _refDecFrame;
312 delete [] _sourceBuffer;
313 _sourceBuffer = NULL;
322 UnitTest::DecodeWithoutAssert()
324 EncodedImage encodedImage;
325 VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
326 int ret = _decoder->Decode(encodedImage, 0, NULL);
327 int frameLength = WaitForDecodedFrame();
328 _encodedVideoBuffer.SetLength(0);
329 return ret == WEBRTC_VIDEO_CODEC_OK ? frameLength : ret;
335 EncodedImage encodedImage;
336 VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
337 if (encodedImage._length == 0)
339 return WEBRTC_VIDEO_CODEC_OK;
342 encodedImage._frameType = kKeyFrame;
345 int ret = _decoder->Decode(encodedImage, 0, NULL);
346 unsigned int frameLength = WaitForDecodedFrame();
347 assert(ret == WEBRTC_VIDEO_CODEC_OK && (frameLength == 0 || frameLength
348 == _lengthSourceFrame));
349 EXPECT_TRUE(ret == WEBRTC_VIDEO_CODEC_OK && (frameLength == 0 || frameLength
350 == _lengthSourceFrame));
351 _encodedVideoBuffer.SetLength(0);
352 return ret == WEBRTC_VIDEO_CODEC_OK ? frameLength : ret;
355 // Test pure virtual VideoEncoder and VideoDecoder APIs.
361 I420VideoFrame inputImage;
362 EncodedImage encodedImage;
364 //----- Encoder parameter tests -----
366 //-- Calls before InitEncode() --
367 // We want to revert the initialization done in Setup().
368 EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
369 EXPECT_TRUE(_encoder->Encode(_inputVideoBuffer, NULL, NULL)
370 == WEBRTC_VIDEO_CODEC_UNINITIALIZED);
372 //-- InitEncode() errors --
374 EXPECT_TRUE(_encoder->InitEncode(NULL, 1, 1440) ==
375 WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
376 // bit rate exceeds max bit rate
377 int32_t tmpBitRate = _inst.startBitrate;
378 int32_t tmpMaxBitRate = _inst.maxBitrate;
379 _inst.startBitrate = 4000;
380 _inst.maxBitrate = 3000;
381 EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
382 WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
383 _inst.startBitrate = tmpBitRate;
384 _inst.maxBitrate = tmpMaxBitRate; //unspecified value
387 _inst.maxFramerate = 0;
388 EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
389 WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
390 // Seems like we should allow any framerate in range [0, 255].
391 //_inst.frameRate = 100;
392 //EXPECT_TRUE(_encoder->InitEncode(&_inst, 1) == -1); // FAILS
393 _inst.maxFramerate = 30;
396 _inst.startBitrate = -1;
397 EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
398 WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
399 _inst.maxBitrate = _inst.startBitrate - 1;
400 EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
401 WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
402 _inst.maxBitrate = 0;
403 _inst.startBitrate = 300;
406 _inst.maxBitrate = 200;
407 EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
408 WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
409 _inst.maxBitrate = 4000;
413 EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) < 0);
414 _inst.width = _source->GetWidth();
418 EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) < 0);
419 _inst.height = _source->GetHeight();
421 // Bad number of cores.
422 EXPECT_TRUE(_encoder->InitEncode(&_inst, -1, 1440) ==
423 WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
425 EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
427 //-- Encode() errors --
428 inputImage.ResetSize();
429 EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
430 WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
431 int width = _source->GetWidth();
432 int half_width = (width + 1) / 2;
433 int height = _source->GetHeight();
434 int half_height = (height + 1) / 2;
435 int size_y = width * height;
436 int size_uv = half_width * half_height;
437 _inputVideoBuffer.CreateFrame(size_y, _refFrame,
438 size_uv, _refFrame + size_y,
439 size_uv, _refFrame + size_y + size_uv,
441 width, half_width, half_width);
442 //----- Encoder stress tests -----
444 // Vary frame rate and I-frame request.
445 for (int i = 1; i <= 60; i++)
447 VideoFrameType frame_type = !(i % 2) ? kKeyFrame : kDeltaFrame;
448 std::vector<VideoFrameType> frame_types(1, frame_type);
449 EXPECT_TRUE(_encoder->Encode(_inputVideoBuffer, NULL, &frame_types) ==
450 WEBRTC_VIDEO_CODEC_OK);
451 EXPECT_TRUE(WaitForEncodedFrame() > 0);
455 _encodedVideoBuffer.SetLength(0);
456 EXPECT_TRUE(_encoder->Encode(_inputVideoBuffer, NULL, NULL) ==
457 WEBRTC_VIDEO_CODEC_OK);
458 EXPECT_TRUE(WaitForEncodedFrame() > 0);
460 EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
461 _encoder->Encode(_inputVideoBuffer, NULL, NULL);
462 frameLength = WaitForEncodedFrame();
463 EXPECT_TRUE(frameLength > 0);
464 EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
465 _encodedVideoBuffer.Buffer(), frameLength) == true);
467 // Reset then encode.
468 _encodedVideoBuffer.SetLength(0);
469 EXPECT_TRUE(_encoder->Encode(_inputVideoBuffer, NULL, NULL) ==
470 WEBRTC_VIDEO_CODEC_OK);
471 WaitForEncodedFrame();
472 EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
473 _encoder->Encode(_inputVideoBuffer, NULL, NULL);
474 frameLength = WaitForEncodedFrame();
475 EXPECT_TRUE(frameLength > 0);
476 EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
477 _encodedVideoBuffer.Buffer(), frameLength) == true);
479 // Release then encode.
480 _encodedVideoBuffer.SetLength(0);
481 EXPECT_TRUE(_encoder->Encode(_inputVideoBuffer, NULL, NULL) ==
482 WEBRTC_VIDEO_CODEC_OK);
483 WaitForEncodedFrame();
484 EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
485 EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
486 _encoder->Encode(_inputVideoBuffer, NULL, NULL);
487 frameLength = WaitForEncodedFrame();
488 EXPECT_TRUE(frameLength > 0);
489 EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
490 _encodedVideoBuffer.Buffer(), frameLength) == true);
492 //----- Decoder parameter tests -----
494 //-- Calls before InitDecode() --
495 // We want to revert the initialization done in Setup().
496 EXPECT_TRUE(_decoder->Release() == WEBRTC_VIDEO_CODEC_OK);
497 VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
498 EXPECT_TRUE(_decoder->Decode(encodedImage, false, NULL) ==
499 WEBRTC_VIDEO_CODEC_UNINITIALIZED);
500 WaitForDecodedFrame();
501 EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_UNINITIALIZED);
502 EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
503 ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
505 //-- Decode() errors --
506 // Unallocated encodedVideoBuffer.
507 _encodedVideoBuffer.Free();
508 VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
509 encodedImage._length = 10; // Buffer NULL but length > 0
510 EXPECT_EQ(_decoder->Decode(encodedImage, false, NULL),
511 WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
512 _encodedVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
514 //----- Decoder stress tests -----
515 unsigned char* tmpBuf = new unsigned char[_lengthSourceFrame];
517 // "Random" and zero data.
518 // We either expect an error, or at the least, no output.
519 // This relies on the codec's ability to detect an erroneous bitstream.
520 EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
521 EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
522 ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
523 for (int i = 0; i < 100; i++)
525 ASSERT_TRUE(fread(tmpBuf, 1, _refEncFrameLength, _sourceFile)
526 == _refEncFrameLength);
527 _encodedVideoBuffer.CopyFrame(_refEncFrameLength, tmpBuf);
528 VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
529 int ret = _decoder->Decode(encodedImage, false, NULL);
530 EXPECT_TRUE(ret <= 0);
533 EXPECT_TRUE(WaitForDecodedFrame() == 0);
536 memset(tmpBuf, 0, _refEncFrameLength);
537 _encodedVideoBuffer.CopyFrame(_refEncFrameLength, tmpBuf);
538 VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
540 // First frame is a key frame.
541 is_key_frame_ = true;
543 ret = _decoder->Decode(encodedImage, false, NULL);
544 EXPECT_TRUE(ret <= 0);
547 EXPECT_TRUE(WaitForDecodedFrame() == 0);
552 _encodedVideoBuffer.SetLength(_refEncFrameLength);
553 _encodedVideoBuffer.CopyFrame(_refEncFrameLength, _refEncFrame);
556 EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
557 ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
559 VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
560 // first frame is a key frame.
561 encodedImage._frameType = kKeyFrame;
562 while (frameLength == 0)
564 _decoder->Decode(encodedImage, false, NULL);
565 frameLength = WaitForDecodedFrame();
567 unsigned int length = CalcBufferSize(kI420, width, height);
568 scoped_ptr<uint8_t[]> decoded_buffer(new uint8_t[length]);
569 ExtractBuffer(_decodedVideoBuffer, _lengthSourceFrame,
570 decoded_buffer.get());
571 EXPECT_TRUE(CheckIfBitExact(decoded_buffer.get(), frameLength, _refDecFrame,
572 _lengthSourceFrame) == true);
574 // Reset then decode.
575 EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
577 VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
578 while (frameLength == 0)
580 _decoder->Decode(encodedImage, false, NULL);
581 frameLength = WaitForDecodedFrame();
583 ExtractBuffer(_decodedVideoBuffer, _lengthSourceFrame,
584 decoded_buffer.get());
585 EXPECT_TRUE(CheckIfBitExact(decoded_buffer.get(), frameLength,
586 _refDecFrame, _lengthSourceFrame) == true);
588 // Decode with other size, reset, then decode with original size again
589 // to verify that decoder is reset to a "fresh" state upon Reset().
591 // Assert that input frame size is a factor of two, so that we can use
592 // quarter size below.
593 EXPECT_TRUE((_inst.width % 2 == 0) && (_inst.height % 2 == 0));
596 memcpy(&tempInst, &_inst, sizeof(VideoCodec));
598 tempInst.height /= 2;
599 int tmpHalfWidth = (tempInst.width + 1) / 2;
600 int tmpHalfHeight = (tempInst.height + 1) / 2;
602 int tmpSizeY = tempInst.width * tempInst.height;
603 int tmpSizeUv = tmpHalfWidth * tmpHalfHeight;
605 // Encode reduced (quarter) frame size.
606 EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
607 EXPECT_TRUE(_encoder->InitEncode(&tempInst, 1, 1440) ==
608 WEBRTC_VIDEO_CODEC_OK);
609 webrtc::I420VideoFrame tempInput;
610 tempInput.CreateFrame(tmpSizeY, _inputVideoBuffer.buffer(kYPlane),
611 tmpSizeUv, _inputVideoBuffer.buffer(kUPlane),
612 tmpSizeUv, _inputVideoBuffer.buffer(kVPlane),
613 tempInst.width, tempInst.height,
614 tempInst.width, tmpHalfWidth, tmpHalfWidth);
615 _encoder->Encode(tempInput, NULL, NULL);
616 frameLength = WaitForEncodedFrame();
617 EXPECT_TRUE(frameLength > 0);
618 // Reset then decode.
619 EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
621 VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
622 while (frameLength == 0)
624 _decoder->Decode(encodedImage, false, NULL);
625 frameLength = WaitForDecodedFrame();
628 // Encode original frame again
629 EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
630 EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
631 WEBRTC_VIDEO_CODEC_OK);
632 _encoder->Encode(_inputVideoBuffer, NULL, NULL);
633 frameLength = WaitForEncodedFrame();
634 EXPECT_TRUE(frameLength > 0);
636 // Reset then decode original frame again.
637 EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
639 VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
640 while (frameLength == 0)
642 _decoder->Decode(encodedImage, false, NULL);
643 frameLength = WaitForDecodedFrame();
646 // check that decoded frame matches with reference
647 unsigned int length = CalcBufferSize(kI420, width, height);
648 scoped_ptr<uint8_t[]> decoded_buffer(new uint8_t[length]);
649 ExtractBuffer(_decodedVideoBuffer, length, decoded_buffer.get());
650 EXPECT_TRUE(CheckIfBitExact(decoded_buffer.get(), length,
651 _refDecFrame, _lengthSourceFrame) == true);
654 // Release then decode.
655 EXPECT_TRUE(_decoder->Release() == WEBRTC_VIDEO_CODEC_OK);
656 EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
657 ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
659 VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
660 while (frameLength == 0)
662 _decoder->Decode(encodedImage, false, NULL);
663 frameLength = WaitForDecodedFrame();
665 ExtractBuffer(_decodedVideoBuffer, length, decoded_buffer.get());
666 EXPECT_TRUE(CheckIfBitExact(decoded_buffer.get(), frameLength,
667 _refDecFrame, _lengthSourceFrame) == true);
668 _encodedVideoBuffer.SetLength(0);
672 //----- Function tests -----
674 // Do not specify maxBitRate (as in ViE).
675 _inst.maxBitrate = 0;
677 //-- Timestamp propagation --
678 EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
679 EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
680 EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
681 ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
686 _decodedVideoBuffer.set_timestamp(0);
687 while (fread(_sourceBuffer, 1, _lengthSourceFrame, _sourceFile) ==
690 _inputVideoBuffer.CreateFrame(size_y, _sourceBuffer,
691 size_uv, _sourceBuffer + size_y,
692 size_uv, _sourceBuffer + size_y + size_uv,
694 width, half_width, half_width);
696 _inputVideoBuffer.set_timestamp(frames);
697 ASSERT_TRUE(_encoder->Encode(_inputVideoBuffer, NULL, NULL) ==
698 WEBRTC_VIDEO_CODEC_OK);
699 frameLength = WaitForEncodedFrame();
700 //ASSERT_TRUE(frameLength);
701 EXPECT_TRUE(frameLength > 0);
702 encTimeStamp = _encodedVideoBuffer.TimeStamp();
703 EXPECT_TRUE(_inputVideoBuffer.timestamp() ==
704 static_cast<unsigned>(encTimeStamp));
706 // First frame is always a key frame.
707 is_key_frame_ = true;
710 frameLength = Decode();
711 if (frameLength == 0)
716 encTimeStamp -= frameDelay;
717 if (encTimeStamp < 0)
721 EXPECT_TRUE(_decodedVideoBuffer.timestamp() ==
722 static_cast<unsigned>(encTimeStamp));
725 ASSERT_TRUE(feof(_sourceFile) != 0);
734 UnitTest::RateControlTests()
737 VideoFrame inputImage;
738 uint32_t frameLength;
740 // Do not specify maxBitRate (as in ViE).
741 _inst.maxBitrate = 0;
742 // Verify rate control. For this test turn on codec frame dropper.
743 // At least one other test (BasicUnitTest) assumes frame dropper off, so
744 // for now we only set frame dropper on for this (rate control) test.
745 _inst.codecSpecific.VP8.frameDroppingOn = true;
746 EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
747 EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
748 EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
749 // add: should also be 0, and 1
750 const int bitRate[] = {100, 500};
751 const int nBitrates = sizeof(bitRate)/sizeof(*bitRate);
753 printf("\nRate control test\n");
754 for (int i = 0; i < nBitrates; i++)
756 _bitRate = bitRate[i];
758 _inst.startBitrate = _bitRate;
759 _encoder->InitEncode(&_inst, 4, 1440);
761 _decoder->InitDecode(&_inst, 1);
764 if (_bitRate > _inst.maxBitrate)
766 CodecSpecific_SetBitrate(_bitRate, _inst.maxFramerate);
770 CodecSpecific_SetBitrate(_bitRate, _inst.maxFramerate);
772 int width = _source->GetWidth();
773 int half_width = (width + 1) / 2;
774 int height = _source->GetHeight();
775 int half_height = (height + 1) / 2;
776 int size_y = width * height;
777 int size_uv = half_width * half_height;
778 while (fread(_sourceBuffer, 1, _lengthSourceFrame, _sourceFile) ==
781 _inputVideoBuffer.CreateFrame(size_y, _sourceBuffer,
782 size_uv, _sourceBuffer + size_y,
783 size_uv, _sourceBuffer + size_y +
786 width, half_width, half_width);
787 _inputVideoBuffer.set_timestamp(static_cast<uint32_t>(9e4 /
788 static_cast<float>(_inst.maxFramerate)));
789 ASSERT_EQ(_encoder->Encode(_inputVideoBuffer, NULL, NULL),
790 WEBRTC_VIDEO_CODEC_OK);
791 frameLength = WaitForEncodedFrame();
792 ASSERT_GE(frameLength, 0u);
793 totalBytes += frameLength;
796 _encodedVideoBuffer.SetLength(0);
798 uint32_t actualBitrate =
799 (totalBytes / frames * _inst.maxFramerate * 8)/1000;
800 printf("Target bitrate: %d kbps, actual bitrate: %d kbps\n", _bitRate,
802 // Test for close match over reasonable range.
803 EXPECT_TRUE(abs(int32_t(actualBitrate - _bitRate)) <
805 ASSERT_TRUE(feof(_sourceFile) != 0);
811 UnitTest::CheckIfBitExact(const void* ptrA, unsigned int aLengthBytes,
812 const void* ptrB, unsigned int bLengthBytes)
814 if (aLengthBytes != bLengthBytes)
819 return memcmp(ptrA, ptrB, aLengthBytes) == 0;