PageRenderTime 65ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/CSipSimple/jni/webrtc/sources/modules/video_coding/codecs/test_framework/unit_test.cc

https://bitbucket.org/bohlooli/csipsimple
C++ | 781 lines | 621 code | 92 blank | 68 comment | 121 complexity | ecb675953d3c1fa2b09d51db1a813e54 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, LGPL-3.0, GPL-3.0, GPL-2.0
  1. /*
  2. * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  3. *
  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.
  9. */
  10. #include <math.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <cassert>
  14. #include "gtest/gtest.h"
  15. #include "testsupport/fileutils.h"
  16. #include "tick_util.h"
  17. #include "unit_test.h"
  18. #include "video_source.h"
  19. using namespace webrtc;
  20. UnitTest::UnitTest()
  21. :
  22. CodecTest("UnitTest", "Unit test"),
  23. _tests(0),
  24. _errors(0),
  25. _source(NULL),
  26. _refFrame(NULL),
  27. _refEncFrame(NULL),
  28. _refDecFrame(NULL),
  29. _refEncFrameLength(0),
  30. _sourceFile(NULL),
  31. _encodeCompleteCallback(NULL),
  32. _decodeCompleteCallback(NULL)
  33. {
  34. }
  35. UnitTest::UnitTest(std::string name, std::string description)
  36. :
  37. CodecTest(name, description),
  38. _tests(0),
  39. _errors(0),
  40. _source(NULL),
  41. _refFrame(NULL),
  42. _refEncFrame(NULL),
  43. _refDecFrame(NULL),
  44. _refEncFrameLength(0),
  45. _sourceFile(NULL),
  46. _encodeCompleteCallback(NULL),
  47. _decodeCompleteCallback(NULL)
  48. {
  49. }
  50. UnitTest::~UnitTest()
  51. {
  52. if (_encodeCompleteCallback) {
  53. delete _encodeCompleteCallback;
  54. }
  55. if (_decodeCompleteCallback) {
  56. delete _decodeCompleteCallback;
  57. }
  58. if (_source) {
  59. delete _source;
  60. }
  61. if (_refFrame) {
  62. delete [] _refFrame;
  63. }
  64. if (_refDecFrame) {
  65. delete [] _refDecFrame;
  66. }
  67. if (_sourceBuffer) {
  68. delete [] _sourceBuffer;
  69. }
  70. if (_sourceFile) {
  71. fclose(_sourceFile);
  72. }
  73. if (_refEncFrame) {
  74. delete [] _refEncFrame;
  75. }
  76. }
  77. WebRtc_Word32
  78. UnitTestEncodeCompleteCallback::Encoded(EncodedImage& encodedImage,
  79. const webrtc::CodecSpecificInfo* codecSpecificInfo,
  80. const webrtc::RTPFragmentationHeader*
  81. fragmentation)
  82. {
  83. _encodedVideoBuffer->VerifyAndAllocate(encodedImage._size);
  84. _encodedVideoBuffer->CopyBuffer(encodedImage._size, encodedImage._buffer);
  85. _encodedVideoBuffer->UpdateLength(encodedImage._length);
  86. _encodedVideoBuffer->SetFrameType(encodedImage._frameType);
  87. _encodedVideoBuffer->SetCaptureWidth(
  88. (WebRtc_UWord16)encodedImage._encodedWidth);
  89. _encodedVideoBuffer->SetCaptureHeight(
  90. (WebRtc_UWord16)encodedImage._encodedHeight);
  91. _encodedVideoBuffer->SetTimeStamp(encodedImage._timeStamp);
  92. _encodeComplete = true;
  93. _encodedFrameType = encodedImage._frameType;
  94. return 0;
  95. }
  96. WebRtc_Word32 UnitTestDecodeCompleteCallback::Decoded(VideoFrame& image)
  97. {
  98. _decodedVideoBuffer->CopyBuffer(image.Length(), image.Buffer());
  99. _decodedVideoBuffer->SetWidth(image.Width());
  100. _decodedVideoBuffer->SetHeight(image.Height());
  101. _decodedVideoBuffer->SetTimeStamp(image.TimeStamp());
  102. _decodeComplete = true;
  103. return 0;
  104. }
  105. bool
  106. UnitTestEncodeCompleteCallback::EncodeComplete()
  107. {
  108. if (_encodeComplete)
  109. {
  110. _encodeComplete = false;
  111. return true;
  112. }
  113. return false;
  114. }
  115. VideoFrameType
  116. UnitTestEncodeCompleteCallback::EncodedFrameType() const
  117. {
  118. return _encodedFrameType;
  119. }
  120. bool
  121. UnitTestDecodeCompleteCallback::DecodeComplete()
  122. {
  123. if (_decodeComplete)
  124. {
  125. _decodeComplete = false;
  126. return true;
  127. }
  128. return false;
  129. }
  130. WebRtc_UWord32
  131. UnitTest::WaitForEncodedFrame() const
  132. {
  133. WebRtc_Word64 startTime = TickTime::MillisecondTimestamp();
  134. while (TickTime::MillisecondTimestamp() - startTime < kMaxWaitEncTimeMs)
  135. {
  136. if (_encodeCompleteCallback->EncodeComplete())
  137. {
  138. return _encodedVideoBuffer.GetLength();
  139. }
  140. }
  141. return 0;
  142. }
  143. WebRtc_UWord32
  144. UnitTest::WaitForDecodedFrame() const
  145. {
  146. WebRtc_Word64 startTime = TickTime::MillisecondTimestamp();
  147. while (TickTime::MillisecondTimestamp() - startTime < kMaxWaitDecTimeMs)
  148. {
  149. if (_decodeCompleteCallback->DecodeComplete())
  150. {
  151. return _decodedVideoBuffer.GetLength();
  152. }
  153. }
  154. return 0;
  155. }
  156. WebRtc_UWord32
  157. UnitTest::CodecSpecific_SetBitrate(WebRtc_UWord32 bitRate,
  158. WebRtc_UWord32 /* frameRate */)
  159. {
  160. return _encoder->SetRates(bitRate, _inst.maxFramerate);
  161. }
  162. void
  163. UnitTest::Setup()
  164. {
  165. // Use _sourceFile as a check to prevent multiple Setup() calls.
  166. if (_sourceFile != NULL)
  167. {
  168. return;
  169. }
  170. if (_encodeCompleteCallback == NULL)
  171. {
  172. _encodeCompleteCallback =
  173. new UnitTestEncodeCompleteCallback(&_encodedVideoBuffer);
  174. }
  175. if (_decodeCompleteCallback == NULL)
  176. {
  177. _decodeCompleteCallback =
  178. new UnitTestDecodeCompleteCallback(&_decodedVideoBuffer);
  179. }
  180. _encoder->RegisterEncodeCompleteCallback(_encodeCompleteCallback);
  181. _decoder->RegisterDecodeCompleteCallback(_decodeCompleteCallback);
  182. _source = new VideoSource(webrtc::test::ProjectRootPath() +
  183. "resources/foreman_cif.yuv", kCIF);
  184. _lengthSourceFrame = _source->GetFrameLength();
  185. _refFrame = new unsigned char[_lengthSourceFrame];
  186. _refDecFrame = new unsigned char[_lengthSourceFrame];
  187. _sourceBuffer = new unsigned char [_lengthSourceFrame];
  188. _sourceFile = fopen(_source->GetFileName().c_str(), "rb");
  189. ASSERT_TRUE(_sourceFile != NULL);
  190. _inst.maxFramerate = _source->GetFrameRate();
  191. _bitRate = 300;
  192. _inst.startBitrate = 300;
  193. _inst.maxBitrate = 4000;
  194. _inst.width = _source->GetWidth();
  195. _inst.height = _source->GetHeight();
  196. _inst.codecSpecific.VP8.denoisingOn = true;
  197. // Get input frame.
  198. _inputVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
  199. ASSERT_TRUE(fread(_refFrame, 1, _lengthSourceFrame, _sourceFile)
  200. == _lengthSourceFrame);
  201. _inputVideoBuffer.CopyBuffer(_lengthSourceFrame, _refFrame);
  202. _inputVideoBuffer.SetWidth(_source->GetWidth());
  203. _inputVideoBuffer.SetHeight(_source->GetHeight());
  204. rewind(_sourceFile);
  205. // Get a reference encoded frame.
  206. _encodedVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
  207. VideoFrame image;
  208. VideoBufferToRawImage(_inputVideoBuffer, image);
  209. // Ensures our initial parameters are valid.
  210. EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
  211. _encoder->Encode(image, NULL, NULL);
  212. _refEncFrameLength = WaitForEncodedFrame();
  213. ASSERT_TRUE(_refEncFrameLength > 0);
  214. _refEncFrame = new unsigned char[_refEncFrameLength];
  215. memcpy(_refEncFrame, _encodedVideoBuffer.GetBuffer(), _refEncFrameLength);
  216. // Get a reference decoded frame.
  217. _decodedVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
  218. EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
  219. ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
  220. unsigned int frameLength = 0;
  221. int i=0;
  222. while (frameLength == 0)
  223. {
  224. if (i > 0)
  225. {
  226. // Insert yet another frame
  227. _inputVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
  228. ASSERT_TRUE(fread(_refFrame, 1, _lengthSourceFrame,
  229. _sourceFile) == _lengthSourceFrame);
  230. _inputVideoBuffer.CopyBuffer(_lengthSourceFrame, _refFrame);
  231. _inputVideoBuffer.SetWidth(_source->GetWidth());
  232. _inputVideoBuffer.SetHeight(_source->GetHeight());
  233. VideoBufferToRawImage(_inputVideoBuffer, image);
  234. _encoder->Encode(image, NULL, NULL);
  235. ASSERT_TRUE(WaitForEncodedFrame() > 0);
  236. }
  237. EncodedImage encodedImage;
  238. VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
  239. ASSERT_TRUE(_decoder->Decode(encodedImage, 0, NULL)
  240. == WEBRTC_VIDEO_CODEC_OK);
  241. frameLength = WaitForDecodedFrame();
  242. _encodedVideoBuffer.Reset();
  243. _encodedVideoBuffer.UpdateLength(0);
  244. i++;
  245. }
  246. rewind(_sourceFile);
  247. EXPECT_TRUE(frameLength == _lengthSourceFrame);
  248. memcpy(_refDecFrame, _decodedVideoBuffer.GetBuffer(), _lengthSourceFrame);
  249. }
  250. void
  251. UnitTest::Teardown()
  252. {
  253. // Use _sourceFile as a check to prevent multiple Teardown() calls.
  254. if (_sourceFile == NULL)
  255. {
  256. return;
  257. }
  258. _encoder->Release();
  259. _decoder->Release();
  260. fclose(_sourceFile);
  261. _sourceFile = NULL;
  262. delete [] _refFrame;
  263. _refFrame = NULL;
  264. delete [] _refEncFrame;
  265. _refEncFrame = NULL;
  266. delete [] _refDecFrame;
  267. _refDecFrame = NULL;
  268. delete [] _sourceBuffer;
  269. _sourceBuffer = NULL;
  270. }
  271. void
  272. UnitTest::Print()
  273. {
  274. }
  275. int
  276. UnitTest::DecodeWithoutAssert()
  277. {
  278. EncodedImage encodedImage;
  279. VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
  280. int ret = _decoder->Decode(encodedImage, 0, NULL);
  281. int frameLength = WaitForDecodedFrame();
  282. _encodedVideoBuffer.Reset();
  283. _encodedVideoBuffer.UpdateLength(0);
  284. return ret == WEBRTC_VIDEO_CODEC_OK ? frameLength : ret;
  285. }
  286. int
  287. UnitTest::Decode()
  288. {
  289. EncodedImage encodedImage;
  290. VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
  291. if (encodedImage._length == 0)
  292. {
  293. return WEBRTC_VIDEO_CODEC_OK;
  294. }
  295. int ret = _decoder->Decode(encodedImage, 0, NULL);
  296. unsigned int frameLength = WaitForDecodedFrame();
  297. assert(ret == WEBRTC_VIDEO_CODEC_OK && (frameLength == 0 || frameLength
  298. == _lengthSourceFrame));
  299. EXPECT_TRUE(ret == WEBRTC_VIDEO_CODEC_OK && (frameLength == 0 || frameLength
  300. == _lengthSourceFrame));
  301. _encodedVideoBuffer.Reset();
  302. _encodedVideoBuffer.UpdateLength(0);
  303. return ret == WEBRTC_VIDEO_CODEC_OK ? frameLength : ret;
  304. }
  305. // Test pure virtual VideoEncoder and VideoDecoder APIs.
  306. void
  307. UnitTest::Perform()
  308. {
  309. UnitTest::Setup();
  310. int frameLength;
  311. VideoFrame inputImage;
  312. EncodedImage encodedImage;
  313. //----- Encoder parameter tests -----
  314. //-- Calls before InitEncode() --
  315. // We want to revert the initialization done in Setup().
  316. EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
  317. VideoBufferToRawImage(_inputVideoBuffer, inputImage);
  318. EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL)
  319. == WEBRTC_VIDEO_CODEC_UNINITIALIZED);
  320. //-- InitEncode() errors --
  321. // Null pointer.
  322. EXPECT_TRUE(_encoder->InitEncode(NULL, 1, 1440) ==
  323. WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
  324. // bit rate exceeds max bit rate
  325. WebRtc_Word32 tmpBitRate = _inst.startBitrate;
  326. WebRtc_Word32 tmpMaxBitRate = _inst.maxBitrate;
  327. _inst.startBitrate = 4000;
  328. _inst.maxBitrate = 3000;
  329. EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
  330. WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
  331. _inst.startBitrate = tmpBitRate;
  332. _inst.maxBitrate = tmpMaxBitRate; //unspecified value
  333. // Bad framerate.
  334. _inst.maxFramerate = 0;
  335. EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
  336. WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
  337. // Seems like we should allow any framerate in range [0, 255].
  338. //_inst.frameRate = 100;
  339. //EXPECT_TRUE(_encoder->InitEncode(&_inst, 1) == -1); // FAILS
  340. _inst.maxFramerate = 30;
  341. // Bad bitrate.
  342. _inst.startBitrate = -1;
  343. EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
  344. WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
  345. _inst.maxBitrate = _inst.startBitrate - 1;
  346. EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
  347. WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
  348. _inst.maxBitrate = 0;
  349. _inst.startBitrate = 300;
  350. // Bad maxBitRate.
  351. _inst.maxBitrate = 200;
  352. EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
  353. WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
  354. _inst.maxBitrate = 4000;
  355. // Bad width.
  356. _inst.width = 0;
  357. EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) < 0);
  358. _inst.width = _source->GetWidth();
  359. // Bad height.
  360. _inst.height = 0;
  361. EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) < 0);
  362. _inst.height = _source->GetHeight();
  363. // Bad number of cores.
  364. EXPECT_TRUE(_encoder->InitEncode(&_inst, -1, 1440) ==
  365. WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
  366. EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
  367. //-- Encode() errors --
  368. // inputVideoBuffer unallocated.
  369. _inputVideoBuffer.Free();
  370. inputImage.Free();
  371. EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
  372. WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
  373. _inputVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
  374. _inputVideoBuffer.CopyBuffer(_lengthSourceFrame, _refFrame);
  375. _inputVideoBuffer.SetWidth(_source->GetWidth());
  376. _inputVideoBuffer.SetHeight(_source->GetHeight());
  377. //----- Encoder stress tests -----
  378. // Vary frame rate and I-frame request.
  379. VideoBufferToRawImage(_inputVideoBuffer, inputImage);
  380. for (int i = 1; i <= 60; i++)
  381. {
  382. VideoFrameType frame_type = !(i % 2) ? kKeyFrame : kDeltaFrame;
  383. std::vector<VideoFrameType> frame_types(1, frame_type);
  384. EXPECT_TRUE(_encoder->Encode(inputImage, NULL, &frame_types) ==
  385. WEBRTC_VIDEO_CODEC_OK);
  386. EXPECT_TRUE(WaitForEncodedFrame() > 0);
  387. }
  388. // Init then encode.
  389. _encodedVideoBuffer.UpdateLength(0);
  390. _encodedVideoBuffer.Reset();
  391. EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
  392. WEBRTC_VIDEO_CODEC_OK);
  393. EXPECT_TRUE(WaitForEncodedFrame() > 0);
  394. EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
  395. _encoder->Encode(inputImage, NULL, NULL);
  396. frameLength = WaitForEncodedFrame();
  397. EXPECT_TRUE(frameLength > 0);
  398. EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
  399. _encodedVideoBuffer.GetBuffer(), frameLength) == true);
  400. // Reset then encode.
  401. _encodedVideoBuffer.UpdateLength(0);
  402. _encodedVideoBuffer.Reset();
  403. EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
  404. WEBRTC_VIDEO_CODEC_OK);
  405. WaitForEncodedFrame();
  406. EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
  407. _encoder->Encode(inputImage, NULL, NULL);
  408. frameLength = WaitForEncodedFrame();
  409. EXPECT_TRUE(frameLength > 0);
  410. EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
  411. _encodedVideoBuffer.GetBuffer(), frameLength) == true);
  412. // Release then encode.
  413. _encodedVideoBuffer.UpdateLength(0);
  414. _encodedVideoBuffer.Reset();
  415. EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
  416. WEBRTC_VIDEO_CODEC_OK);
  417. WaitForEncodedFrame();
  418. EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
  419. EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
  420. _encoder->Encode(inputImage, NULL, NULL);
  421. frameLength = WaitForEncodedFrame();
  422. EXPECT_TRUE(frameLength > 0);
  423. EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
  424. _encodedVideoBuffer.GetBuffer(), frameLength) == true);
  425. //----- Decoder parameter tests -----
  426. //-- Calls before InitDecode() --
  427. // We want to revert the initialization done in Setup().
  428. EXPECT_TRUE(_decoder->Release() == WEBRTC_VIDEO_CODEC_OK);
  429. VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
  430. EXPECT_TRUE(_decoder->Decode(encodedImage, false, NULL) ==
  431. WEBRTC_VIDEO_CODEC_UNINITIALIZED);
  432. WaitForDecodedFrame();
  433. EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_UNINITIALIZED);
  434. EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
  435. ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
  436. //-- Decode() errors --
  437. // Unallocated encodedVideoBuffer.
  438. _encodedVideoBuffer.Free();
  439. VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
  440. encodedImage._length = 10; // Buffer NULL but length > 0
  441. EXPECT_EQ(_decoder->Decode(encodedImage, false, NULL),
  442. WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
  443. _encodedVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
  444. //----- Decoder stress tests -----
  445. unsigned char* tmpBuf = new unsigned char[_lengthSourceFrame];
  446. // "Random" and zero data.
  447. // We either expect an error, or at the least, no output.
  448. // This relies on the codec's ability to detect an erroneous bitstream.
  449. EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
  450. EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
  451. ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
  452. for (int i = 0; i < 100; i++)
  453. {
  454. ASSERT_TRUE(fread(tmpBuf, 1, _refEncFrameLength, _sourceFile)
  455. == _refEncFrameLength);
  456. _encodedVideoBuffer.CopyBuffer(_refEncFrameLength, tmpBuf);
  457. VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
  458. int ret = _decoder->Decode(encodedImage, false, NULL);
  459. EXPECT_TRUE(ret <= 0);
  460. if (ret == 0)
  461. {
  462. EXPECT_TRUE(WaitForDecodedFrame() == 0);
  463. }
  464. memset(tmpBuf, 0, _refEncFrameLength);
  465. _encodedVideoBuffer.CopyBuffer(_refEncFrameLength, tmpBuf);
  466. VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
  467. ret = _decoder->Decode(encodedImage, false, NULL);
  468. EXPECT_TRUE(ret <= 0);
  469. if (ret == 0)
  470. {
  471. EXPECT_TRUE(WaitForDecodedFrame() == 0);
  472. }
  473. }
  474. rewind(_sourceFile);
  475. _encodedVideoBuffer.UpdateLength(_refEncFrameLength);
  476. _encodedVideoBuffer.CopyBuffer(_refEncFrameLength, _refEncFrame);
  477. // Init then decode.
  478. EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
  479. ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
  480. frameLength = 0;
  481. VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
  482. while (frameLength == 0)
  483. {
  484. _decoder->Decode(encodedImage, false, NULL);
  485. frameLength = WaitForDecodedFrame();
  486. }
  487. EXPECT_TRUE(CheckIfBitExact(_decodedVideoBuffer.GetBuffer(), frameLength,
  488. _refDecFrame, _lengthSourceFrame) == true);
  489. // Reset then decode.
  490. EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
  491. frameLength = 0;
  492. VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
  493. while (frameLength == 0)
  494. {
  495. _decoder->Decode(encodedImage, false, NULL);
  496. frameLength = WaitForDecodedFrame();
  497. }
  498. EXPECT_TRUE(CheckIfBitExact(_decodedVideoBuffer.GetBuffer(), frameLength,
  499. _refDecFrame, _lengthSourceFrame) == true);
  500. // Decode with other size, reset, then decode with original size again
  501. // to verify that decoder is reset to a "fresh" state upon Reset().
  502. {
  503. // Assert that input frame size is a factor of two, so that we can use
  504. // quarter size below.
  505. EXPECT_TRUE((_inst.width % 2 == 0) && (_inst.height % 2 == 0));
  506. VideoCodec tempInst;
  507. memcpy(&tempInst, &_inst, sizeof(VideoCodec));
  508. tempInst.width /= 2;
  509. tempInst.height /= 2;
  510. // Encode reduced (quarter) frame size.
  511. EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
  512. EXPECT_TRUE(_encoder->InitEncode(&tempInst, 1, 1440) ==
  513. WEBRTC_VIDEO_CODEC_OK);
  514. VideoFrame tempInput;
  515. unsigned int tmpLength = inputImage.Length() / 4;
  516. tempInput.CopyFrame(tmpLength, inputImage.Buffer());
  517. tempInput.SetWidth(tempInst.width);
  518. tempInput.SetHeight(tempInst.height);
  519. _encoder->Encode(tempInput, NULL, NULL);
  520. frameLength = WaitForEncodedFrame();
  521. EXPECT_TRUE(frameLength > 0);
  522. tempInput.Free();
  523. // Reset then decode.
  524. EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
  525. frameLength = 0;
  526. VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
  527. while (frameLength == 0)
  528. {
  529. _decoder->Decode(encodedImage, false, NULL);
  530. frameLength = WaitForDecodedFrame();
  531. }
  532. // Encode original frame again
  533. EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
  534. EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
  535. WEBRTC_VIDEO_CODEC_OK);
  536. _encoder->Encode(inputImage, NULL, NULL);
  537. frameLength = WaitForEncodedFrame();
  538. EXPECT_TRUE(frameLength > 0);
  539. // Reset then decode original frame again.
  540. EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
  541. frameLength = 0;
  542. VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
  543. while (frameLength == 0)
  544. {
  545. _decoder->Decode(encodedImage, false, NULL);
  546. frameLength = WaitForDecodedFrame();
  547. }
  548. // check that decoded frame matches with reference
  549. EXPECT_TRUE(CheckIfBitExact(_decodedVideoBuffer.GetBuffer(), frameLength,
  550. _refDecFrame, _lengthSourceFrame) == true);
  551. }
  552. // Release then decode.
  553. EXPECT_TRUE(_decoder->Release() == WEBRTC_VIDEO_CODEC_OK);
  554. EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
  555. ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
  556. frameLength = 0;
  557. VideoEncodedBufferToEncodedImage(_encodedVideoBuffer, encodedImage);
  558. while (frameLength == 0)
  559. {
  560. _decoder->Decode(encodedImage, false, NULL);
  561. frameLength = WaitForDecodedFrame();
  562. }
  563. EXPECT_TRUE(CheckIfBitExact(_decodedVideoBuffer.GetBuffer(), frameLength,
  564. _refDecFrame, _lengthSourceFrame) == true);
  565. _encodedVideoBuffer.UpdateLength(0);
  566. _encodedVideoBuffer.Reset();
  567. delete [] tmpBuf;
  568. //----- Function tests -----
  569. int frames = 0;
  570. // Do not specify maxBitRate (as in ViE).
  571. _inst.maxBitrate = 0;
  572. //-- Timestamp propagation --
  573. EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
  574. EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
  575. EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
  576. ASSERT_FALSE(SetCodecSpecificParameters() != WEBRTC_VIDEO_CODEC_OK);
  577. frames = 0;
  578. int frameDelay = 0;
  579. int encTimeStamp;
  580. _decodedVideoBuffer.SetTimeStamp(0);
  581. while (fread(_sourceBuffer, 1, _lengthSourceFrame, _sourceFile) ==
  582. _lengthSourceFrame)
  583. {
  584. _inputVideoBuffer.CopyBuffer(_lengthSourceFrame, _sourceBuffer);
  585. _inputVideoBuffer.SetTimeStamp(frames);
  586. VideoBufferToRawImage(_inputVideoBuffer, inputImage);
  587. ASSERT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
  588. WEBRTC_VIDEO_CODEC_OK);
  589. frameLength = WaitForEncodedFrame();
  590. //ASSERT_TRUE(frameLength);
  591. EXPECT_TRUE(frameLength > 0);
  592. encTimeStamp = _encodedVideoBuffer.GetTimeStamp();
  593. EXPECT_TRUE(_inputVideoBuffer.GetTimeStamp() ==
  594. static_cast<unsigned>(encTimeStamp));
  595. frameLength = Decode();
  596. if (frameLength == 0)
  597. {
  598. frameDelay++;
  599. }
  600. encTimeStamp -= frameDelay;
  601. if (encTimeStamp < 0)
  602. {
  603. encTimeStamp = 0;
  604. }
  605. EXPECT_TRUE(_decodedVideoBuffer.GetTimeStamp() ==
  606. static_cast<unsigned>(encTimeStamp));
  607. frames++;
  608. }
  609. ASSERT_TRUE(feof(_sourceFile) != 0);
  610. rewind(_sourceFile);
  611. RateControlTests();
  612. inputImage.Free();
  613. Teardown();
  614. }
  615. void
  616. UnitTest::RateControlTests()
  617. {
  618. int frames = 0;
  619. VideoFrame inputImage;
  620. WebRtc_UWord32 frameLength;
  621. // Do not specify maxBitRate (as in ViE).
  622. _inst.maxBitrate = 0;
  623. //-- Verify rate control --
  624. EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
  625. EXPECT_TRUE(_decoder->Reset() == WEBRTC_VIDEO_CODEC_OK);
  626. EXPECT_TRUE(_decoder->InitDecode(&_inst, 1) == WEBRTC_VIDEO_CODEC_OK);
  627. // add: should also be 0, and 1
  628. const int bitRate[] = {30, 100, 500, 1000, 2000};
  629. const int nBitrates = sizeof(bitRate)/sizeof(*bitRate);
  630. printf("\nRate control test\n");
  631. for (int i = 0; i < nBitrates; i++)
  632. {
  633. _bitRate = bitRate[i];
  634. int totalBytes = 0;
  635. _inst.startBitrate = _bitRate;
  636. _encoder->InitEncode(&_inst, 4, 1440);
  637. _decoder->Reset();
  638. _decoder->InitDecode(&_inst, 1);
  639. frames = 0;
  640. if (_bitRate > _inst.maxBitrate)
  641. {
  642. CodecSpecific_SetBitrate(_bitRate, _inst.maxFramerate);
  643. }
  644. else
  645. {
  646. CodecSpecific_SetBitrate(_bitRate, _inst.maxFramerate);
  647. }
  648. while (fread(_sourceBuffer, 1, _lengthSourceFrame, _sourceFile) ==
  649. _lengthSourceFrame)
  650. {
  651. _inputVideoBuffer.CopyBuffer(_lengthSourceFrame, _sourceBuffer);
  652. _inputVideoBuffer.SetTimeStamp(_inputVideoBuffer.GetTimeStamp() +
  653. static_cast<WebRtc_UWord32>(9e4 /
  654. static_cast<float>(_inst.maxFramerate)));
  655. VideoBufferToRawImage(_inputVideoBuffer, inputImage);
  656. ASSERT_EQ(_encoder->Encode(inputImage, NULL, NULL),
  657. WEBRTC_VIDEO_CODEC_OK);
  658. frameLength = WaitForEncodedFrame();
  659. ASSERT_GE(frameLength, 0u);
  660. totalBytes += frameLength;
  661. frames++;
  662. _encodedVideoBuffer.UpdateLength(0);
  663. _encodedVideoBuffer.Reset();
  664. }
  665. WebRtc_UWord32 actualBitrate =
  666. (totalBytes / frames * _inst.maxFramerate * 8)/1000;
  667. printf("Target bitrate: %d kbps, actual bitrate: %d kbps\n", _bitRate,
  668. actualBitrate);
  669. // Test for close match over reasonable range.
  670. if (_bitRate >= 100 && _bitRate <= 2500)
  671. {
  672. EXPECT_TRUE(abs(WebRtc_Word32(actualBitrate - _bitRate)) <
  673. 0.12 * _bitRate); // for VP8
  674. }
  675. ASSERT_TRUE(feof(_sourceFile) != 0);
  676. rewind(_sourceFile);
  677. }
  678. inputImage.Free();
  679. }
  680. bool
  681. UnitTest::CheckIfBitExact(const void* ptrA, unsigned int aLengthBytes,
  682. const void* ptrB, unsigned int bLengthBytes)
  683. {
  684. if (aLengthBytes != bLengthBytes)
  685. {
  686. return false;
  687. }
  688. return memcmp(ptrA, ptrB, aLengthBytes) == 0;
  689. }