datarate_test.cc 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670
  1. /*
  2. * Copyright (c) 2012 The WebM 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 "./vpx_config.h"
  11. #include "third_party/googletest/src/include/gtest/gtest.h"
  12. #include "test/codec_factory.h"
  13. #include "test/encode_test_driver.h"
  14. #include "test/i420_video_source.h"
  15. #include "test/util.h"
  16. #include "test/y4m_video_source.h"
  17. #include "vpx/vpx_codec.h"
  18. namespace {
  19. class DatarateTestLarge
  20. : public ::libvpx_test::EncoderTest,
  21. public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
  22. public:
  23. DatarateTestLarge() : EncoderTest(GET_PARAM(0)) {}
  24. virtual ~DatarateTestLarge() {}
  25. protected:
  26. virtual void SetUp() {
  27. InitializeConfig();
  28. SetMode(GET_PARAM(1));
  29. set_cpu_used_ = GET_PARAM(2);
  30. ResetModel();
  31. }
  32. virtual void ResetModel() {
  33. last_pts_ = 0;
  34. bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
  35. frame_number_ = 0;
  36. first_drop_ = 0;
  37. bits_total_ = 0;
  38. duration_ = 0.0;
  39. denoiser_offon_test_ = 0;
  40. denoiser_offon_period_ = -1;
  41. gf_boost_ = 0;
  42. }
  43. virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
  44. ::libvpx_test::Encoder *encoder) {
  45. if (video->frame() == 0) {
  46. encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
  47. encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
  48. encoder->Control(VP8E_SET_GF_CBR_BOOST_PCT, gf_boost_);
  49. }
  50. if (denoiser_offon_test_) {
  51. ASSERT_GT(denoiser_offon_period_, 0)
  52. << "denoiser_offon_period_ is not positive.";
  53. if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
  54. // Flip denoiser_on_ periodically
  55. denoiser_on_ ^= 1;
  56. }
  57. encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
  58. }
  59. const vpx_rational_t tb = video->timebase();
  60. timebase_ = static_cast<double>(tb.num) / tb.den;
  61. duration_ = 0;
  62. }
  63. virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
  64. // Time since last timestamp = duration.
  65. vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
  66. // TODO(jimbankoski): Remove these lines when the issue:
  67. // http://code.google.com/p/webm/issues/detail?id=496 is fixed.
  68. // For now the codec assumes buffer starts at starting buffer rate
  69. // plus one frame's time.
  70. if (last_pts_ == 0) duration = 1;
  71. // Add to the buffer the bits we'd expect from a constant bitrate server.
  72. bits_in_buffer_model_ += static_cast<int64_t>(
  73. duration * timebase_ * cfg_.rc_target_bitrate * 1000);
  74. /* Test the buffer model here before subtracting the frame. Do so because
  75. * the way the leaky bucket model works in libvpx is to allow the buffer to
  76. * empty - and then stop showing frames until we've got enough bits to
  77. * show one. As noted in comment below (issue 495), this does not currently
  78. * apply to key frames. For now exclude key frames in condition below. */
  79. const bool key_frame =
  80. (pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
  81. if (!key_frame) {
  82. ASSERT_GE(bits_in_buffer_model_, 0)
  83. << "Buffer Underrun at frame " << pkt->data.frame.pts;
  84. }
  85. const int64_t frame_size_in_bits = pkt->data.frame.sz * 8;
  86. // Subtract from the buffer the bits associated with a played back frame.
  87. bits_in_buffer_model_ -= frame_size_in_bits;
  88. // Update the running total of bits for end of test datarate checks.
  89. bits_total_ += frame_size_in_bits;
  90. // If first drop not set and we have a drop set it to this time.
  91. if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1;
  92. // Update the most recent pts.
  93. last_pts_ = pkt->data.frame.pts;
  94. // We update this so that we can calculate the datarate minus the last
  95. // frame encoded in the file.
  96. bits_in_last_frame_ = frame_size_in_bits;
  97. ++frame_number_;
  98. }
  99. virtual void EndPassHook(void) {
  100. if (bits_total_) {
  101. const double file_size_in_kb = bits_total_ / 1000.; // bits per kilobit
  102. duration_ = (last_pts_ + 1) * timebase_;
  103. // Effective file datarate includes the time spent prebuffering.
  104. effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0 /
  105. (cfg_.rc_buf_initial_sz / 1000.0 + duration_);
  106. file_datarate_ = file_size_in_kb / duration_;
  107. }
  108. }
  109. vpx_codec_pts_t last_pts_;
  110. int64_t bits_in_buffer_model_;
  111. double timebase_;
  112. int frame_number_;
  113. vpx_codec_pts_t first_drop_;
  114. int64_t bits_total_;
  115. double duration_;
  116. double file_datarate_;
  117. double effective_datarate_;
  118. int64_t bits_in_last_frame_;
  119. int denoiser_on_;
  120. int denoiser_offon_test_;
  121. int denoiser_offon_period_;
  122. int set_cpu_used_;
  123. int gf_boost_;
  124. };
  125. #if CONFIG_TEMPORAL_DENOISING
  126. // Check basic datarate targeting, for a single bitrate, but loop over the
  127. // various denoiser settings.
  128. TEST_P(DatarateTestLarge, DenoiserLevels) {
  129. cfg_.rc_buf_initial_sz = 500;
  130. cfg_.rc_dropframe_thresh = 1;
  131. cfg_.rc_max_quantizer = 56;
  132. cfg_.rc_end_usage = VPX_CBR;
  133. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  134. 30, 1, 0, 140);
  135. for (int j = 1; j < 5; ++j) {
  136. // Run over the denoiser levels.
  137. // For the temporal denoiser (#if CONFIG_TEMPORAL_DENOISING) the level j
  138. // refers to the 4 denoiser modes: denoiserYonly, denoiserOnYUV,
  139. // denoiserOnAggressive, and denoiserOnAdaptive.
  140. denoiser_on_ = j;
  141. cfg_.rc_target_bitrate = 300;
  142. ResetModel();
  143. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  144. ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
  145. << " The datarate for the file exceeds the target!";
  146. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
  147. << " The datarate for the file missed the target!";
  148. }
  149. }
  150. // Check basic datarate targeting, for a single bitrate, when denoiser is off
  151. // and on.
  152. TEST_P(DatarateTestLarge, DenoiserOffOn) {
  153. cfg_.rc_buf_initial_sz = 500;
  154. cfg_.rc_dropframe_thresh = 1;
  155. cfg_.rc_max_quantizer = 56;
  156. cfg_.rc_end_usage = VPX_CBR;
  157. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  158. 30, 1, 0, 299);
  159. cfg_.rc_target_bitrate = 300;
  160. ResetModel();
  161. // The denoiser is off by default.
  162. denoiser_on_ = 0;
  163. // Set the offon test flag.
  164. denoiser_offon_test_ = 1;
  165. denoiser_offon_period_ = 100;
  166. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  167. ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
  168. << " The datarate for the file exceeds the target!";
  169. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
  170. << " The datarate for the file missed the target!";
  171. }
  172. #endif // CONFIG_TEMPORAL_DENOISING
  173. TEST_P(DatarateTestLarge, BasicBufferModel) {
  174. denoiser_on_ = 0;
  175. cfg_.rc_buf_initial_sz = 500;
  176. cfg_.rc_dropframe_thresh = 1;
  177. cfg_.rc_max_quantizer = 56;
  178. cfg_.rc_end_usage = VPX_CBR;
  179. // 2 pass cbr datarate control has a bug hidden by the small # of
  180. // frames selected in this encode. The problem is that even if the buffer is
  181. // negative we produce a keyframe on a cutscene. Ignoring datarate
  182. // constraints
  183. // TODO(jimbankoski): ( Fix when issue
  184. // http://code.google.com/p/webm/issues/detail?id=495 is addressed. )
  185. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  186. 30, 1, 0, 140);
  187. // There is an issue for low bitrates in real-time mode, where the
  188. // effective_datarate slightly overshoots the target bitrate.
  189. // This is same the issue as noted about (#495).
  190. // TODO(jimbankoski/marpan): Update test to run for lower bitrates (< 100),
  191. // when the issue is resolved.
  192. for (int i = 100; i < 800; i += 200) {
  193. cfg_.rc_target_bitrate = i;
  194. ResetModel();
  195. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  196. ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
  197. << " The datarate for the file exceeds the target!";
  198. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
  199. << " The datarate for the file missed the target!";
  200. }
  201. }
  202. TEST_P(DatarateTestLarge, ChangingDropFrameThresh) {
  203. denoiser_on_ = 0;
  204. cfg_.rc_buf_initial_sz = 500;
  205. cfg_.rc_max_quantizer = 36;
  206. cfg_.rc_end_usage = VPX_CBR;
  207. cfg_.rc_target_bitrate = 200;
  208. cfg_.kf_mode = VPX_KF_DISABLED;
  209. const int frame_count = 40;
  210. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  211. 30, 1, 0, frame_count);
  212. // Here we check that the first dropped frame gets earlier and earlier
  213. // as the drop frame threshold is increased.
  214. const int kDropFrameThreshTestStep = 30;
  215. vpx_codec_pts_t last_drop = frame_count;
  216. for (int i = 1; i < 91; i += kDropFrameThreshTestStep) {
  217. cfg_.rc_dropframe_thresh = i;
  218. ResetModel();
  219. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  220. ASSERT_LE(first_drop_, last_drop)
  221. << " The first dropped frame for drop_thresh " << i
  222. << " > first dropped frame for drop_thresh "
  223. << i - kDropFrameThreshTestStep;
  224. last_drop = first_drop_;
  225. }
  226. }
  227. TEST_P(DatarateTestLarge, DropFramesMultiThreads) {
  228. denoiser_on_ = 0;
  229. cfg_.rc_buf_initial_sz = 500;
  230. cfg_.rc_dropframe_thresh = 30;
  231. cfg_.rc_max_quantizer = 56;
  232. cfg_.rc_end_usage = VPX_CBR;
  233. cfg_.g_threads = 2;
  234. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  235. 30, 1, 0, 140);
  236. cfg_.rc_target_bitrate = 200;
  237. ResetModel();
  238. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  239. ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
  240. << " The datarate for the file exceeds the target!";
  241. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
  242. << " The datarate for the file missed the target!";
  243. }
  244. class DatarateTestRealTime : public DatarateTestLarge {
  245. public:
  246. virtual ~DatarateTestRealTime() {}
  247. };
  248. #if CONFIG_TEMPORAL_DENOISING
  249. // Check basic datarate targeting, for a single bitrate, but loop over the
  250. // various denoiser settings.
  251. TEST_P(DatarateTestRealTime, DenoiserLevels) {
  252. cfg_.rc_buf_initial_sz = 500;
  253. cfg_.rc_dropframe_thresh = 1;
  254. cfg_.rc_max_quantizer = 56;
  255. cfg_.rc_end_usage = VPX_CBR;
  256. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  257. 30, 1, 0, 140);
  258. for (int j = 1; j < 5; ++j) {
  259. // Run over the denoiser levels.
  260. // For the temporal denoiser (#if CONFIG_TEMPORAL_DENOISING) the level j
  261. // refers to the 4 denoiser modes: denoiserYonly, denoiserOnYUV,
  262. // denoiserOnAggressive, and denoiserOnAdaptive.
  263. denoiser_on_ = j;
  264. cfg_.rc_target_bitrate = 300;
  265. ResetModel();
  266. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  267. ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
  268. << " The datarate for the file exceeds the target!";
  269. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
  270. << " The datarate for the file missed the target!";
  271. }
  272. }
  273. // Check basic datarate targeting, for a single bitrate, when denoiser is off
  274. // and on.
  275. TEST_P(DatarateTestRealTime, DenoiserOffOn) {
  276. cfg_.rc_buf_initial_sz = 500;
  277. cfg_.rc_dropframe_thresh = 1;
  278. cfg_.rc_max_quantizer = 56;
  279. cfg_.rc_end_usage = VPX_CBR;
  280. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  281. 30, 1, 0, 299);
  282. cfg_.rc_target_bitrate = 300;
  283. ResetModel();
  284. // The denoiser is off by default.
  285. denoiser_on_ = 0;
  286. // Set the offon test flag.
  287. denoiser_offon_test_ = 1;
  288. denoiser_offon_period_ = 100;
  289. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  290. ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
  291. << " The datarate for the file exceeds the target!";
  292. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
  293. << " The datarate for the file missed the target!";
  294. }
  295. #endif // CONFIG_TEMPORAL_DENOISING
  296. TEST_P(DatarateTestRealTime, BasicBufferModel) {
  297. denoiser_on_ = 0;
  298. cfg_.rc_buf_initial_sz = 500;
  299. cfg_.rc_dropframe_thresh = 1;
  300. cfg_.rc_max_quantizer = 56;
  301. cfg_.rc_end_usage = VPX_CBR;
  302. // 2 pass cbr datarate control has a bug hidden by the small # of
  303. // frames selected in this encode. The problem is that even if the buffer is
  304. // negative we produce a keyframe on a cutscene, ignoring datarate
  305. // constraints
  306. // TODO(jimbankoski): Fix when issue
  307. // http://bugs.chromium.org/p/webm/issues/detail?id=495 is addressed.
  308. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  309. 30, 1, 0, 140);
  310. // There is an issue for low bitrates in real-time mode, where the
  311. // effective_datarate slightly overshoots the target bitrate.
  312. // This is same the issue as noted above (#495).
  313. // TODO(jimbankoski/marpan): Update test to run for lower bitrates (< 100),
  314. // when the issue is resolved.
  315. for (int i = 100; i <= 700; i += 200) {
  316. cfg_.rc_target_bitrate = i;
  317. ResetModel();
  318. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  319. ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
  320. << " The datarate for the file exceeds the target!";
  321. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
  322. << " The datarate for the file missed the target!";
  323. }
  324. }
  325. TEST_P(DatarateTestRealTime, ChangingDropFrameThresh) {
  326. denoiser_on_ = 0;
  327. cfg_.rc_buf_initial_sz = 500;
  328. cfg_.rc_max_quantizer = 36;
  329. cfg_.rc_end_usage = VPX_CBR;
  330. cfg_.rc_target_bitrate = 200;
  331. cfg_.kf_mode = VPX_KF_DISABLED;
  332. const int frame_count = 40;
  333. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  334. 30, 1, 0, frame_count);
  335. // Check that the first dropped frame gets earlier and earlier
  336. // as the drop frame threshold is increased.
  337. const int kDropFrameThreshTestStep = 30;
  338. vpx_codec_pts_t last_drop = frame_count;
  339. for (int i = 1; i < 91; i += kDropFrameThreshTestStep) {
  340. cfg_.rc_dropframe_thresh = i;
  341. ResetModel();
  342. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  343. ASSERT_LE(first_drop_, last_drop)
  344. << " The first dropped frame for drop_thresh " << i
  345. << " > first dropped frame for drop_thresh "
  346. << i - kDropFrameThreshTestStep;
  347. last_drop = first_drop_;
  348. }
  349. }
  350. TEST_P(DatarateTestRealTime, DropFramesMultiThreads) {
  351. denoiser_on_ = 0;
  352. cfg_.rc_buf_initial_sz = 500;
  353. cfg_.rc_dropframe_thresh = 30;
  354. cfg_.rc_max_quantizer = 56;
  355. cfg_.rc_end_usage = VPX_CBR;
  356. // Encode using multiple threads.
  357. cfg_.g_threads = 2;
  358. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  359. 30, 1, 0, 140);
  360. cfg_.rc_target_bitrate = 200;
  361. ResetModel();
  362. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  363. ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
  364. << " The datarate for the file exceeds the target!";
  365. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
  366. << " The datarate for the file missed the target!";
  367. }
  368. TEST_P(DatarateTestRealTime, GFBoost) {
  369. denoiser_on_ = 0;
  370. cfg_.rc_buf_initial_sz = 500;
  371. cfg_.rc_dropframe_thresh = 0;
  372. cfg_.rc_max_quantizer = 56;
  373. cfg_.rc_end_usage = VPX_CBR;
  374. cfg_.g_error_resilient = 0;
  375. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  376. 30, 1, 0, 300);
  377. cfg_.rc_target_bitrate = 300;
  378. ResetModel();
  379. // Apply a gf boost.
  380. gf_boost_ = 50;
  381. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  382. ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
  383. << " The datarate for the file exceeds the target!";
  384. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
  385. << " The datarate for the file missed the target!";
  386. }
  387. class DatarateTestVP9Large
  388. : public ::libvpx_test::EncoderTest,
  389. public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
  390. public:
  391. DatarateTestVP9Large() : EncoderTest(GET_PARAM(0)) {}
  392. protected:
  393. virtual ~DatarateTestVP9Large() {}
  394. virtual void SetUp() {
  395. InitializeConfig();
  396. SetMode(GET_PARAM(1));
  397. set_cpu_used_ = GET_PARAM(2);
  398. ResetModel();
  399. }
  400. virtual void ResetModel() {
  401. last_pts_ = 0;
  402. bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
  403. frame_number_ = 0;
  404. tot_frame_number_ = 0;
  405. first_drop_ = 0;
  406. num_drops_ = 0;
  407. // Denoiser is off by default.
  408. denoiser_on_ = 0;
  409. // For testing up to 3 layers.
  410. for (int i = 0; i < 3; ++i) {
  411. bits_total_[i] = 0;
  412. }
  413. denoiser_offon_test_ = 0;
  414. denoiser_offon_period_ = -1;
  415. frame_parallel_decoding_mode_ = 1;
  416. }
  417. //
  418. // Frame flags and layer id for temporal layers.
  419. //
  420. // For two layers, test pattern is:
  421. // 1 3
  422. // 0 2 .....
  423. // For three layers, test pattern is:
  424. // 1 3 5 7
  425. // 2 6
  426. // 0 4 ....
  427. // LAST is always update on base/layer 0, GOLDEN is updated on layer 1.
  428. // For this 3 layer example, the 2nd enhancement layer (layer 2) updates
  429. // the altref frame.
  430. int SetFrameFlags(int frame_num, int num_temp_layers) {
  431. int frame_flags = 0;
  432. if (num_temp_layers == 2) {
  433. if (frame_num % 2 == 0) {
  434. // Layer 0: predict from L and ARF, update L.
  435. frame_flags =
  436. VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
  437. } else {
  438. // Layer 1: predict from L, G and ARF, and update G.
  439. frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
  440. VP8_EFLAG_NO_UPD_ENTROPY;
  441. }
  442. } else if (num_temp_layers == 3) {
  443. if (frame_num % 4 == 0) {
  444. // Layer 0: predict from L and ARF; update L.
  445. frame_flags =
  446. VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
  447. } else if ((frame_num - 2) % 4 == 0) {
  448. // Layer 1: predict from L, G, ARF; update G.
  449. frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
  450. } else if ((frame_num - 1) % 2 == 0) {
  451. // Layer 2: predict from L, G, ARF; update ARF.
  452. frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
  453. }
  454. }
  455. return frame_flags;
  456. }
  457. int SetLayerId(int frame_num, int num_temp_layers) {
  458. int layer_id = 0;
  459. if (num_temp_layers == 2) {
  460. if (frame_num % 2 == 0) {
  461. layer_id = 0;
  462. } else {
  463. layer_id = 1;
  464. }
  465. } else if (num_temp_layers == 3) {
  466. if (frame_num % 4 == 0) {
  467. layer_id = 0;
  468. } else if ((frame_num - 2) % 4 == 0) {
  469. layer_id = 1;
  470. } else if ((frame_num - 1) % 2 == 0) {
  471. layer_id = 2;
  472. }
  473. }
  474. return layer_id;
  475. }
  476. virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
  477. ::libvpx_test::Encoder *encoder) {
  478. if (video->frame() == 0) encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
  479. if (denoiser_offon_test_) {
  480. ASSERT_GT(denoiser_offon_period_, 0)
  481. << "denoiser_offon_period_ is not positive.";
  482. if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
  483. // Flip denoiser_on_ periodically
  484. denoiser_on_ ^= 1;
  485. }
  486. }
  487. encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
  488. encoder->Control(VP9E_SET_TILE_COLUMNS, (cfg_.g_threads >> 1));
  489. encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING,
  490. frame_parallel_decoding_mode_);
  491. if (cfg_.ts_number_layers > 1) {
  492. if (video->frame() == 0) {
  493. encoder->Control(VP9E_SET_SVC, 1);
  494. }
  495. vpx_svc_layer_id_t layer_id;
  496. layer_id.spatial_layer_id = 0;
  497. frame_flags_ = SetFrameFlags(video->frame(), cfg_.ts_number_layers);
  498. layer_id.temporal_layer_id =
  499. SetLayerId(video->frame(), cfg_.ts_number_layers);
  500. encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
  501. }
  502. const vpx_rational_t tb = video->timebase();
  503. timebase_ = static_cast<double>(tb.num) / tb.den;
  504. duration_ = 0;
  505. }
  506. virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
  507. // Time since last timestamp = duration.
  508. vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
  509. if (duration > 1) {
  510. // If first drop not set and we have a drop set it to this time.
  511. if (!first_drop_) first_drop_ = last_pts_ + 1;
  512. // Update the number of frame drops.
  513. num_drops_ += static_cast<int>(duration - 1);
  514. // Update counter for total number of frames (#frames input to encoder).
  515. // Needed for setting the proper layer_id below.
  516. tot_frame_number_ += static_cast<int>(duration - 1);
  517. }
  518. int layer = SetLayerId(tot_frame_number_, cfg_.ts_number_layers);
  519. // Add to the buffer the bits we'd expect from a constant bitrate server.
  520. bits_in_buffer_model_ += static_cast<int64_t>(
  521. duration * timebase_ * cfg_.rc_target_bitrate * 1000);
  522. // Buffer should not go negative.
  523. ASSERT_GE(bits_in_buffer_model_, 0)
  524. << "Buffer Underrun at frame " << pkt->data.frame.pts;
  525. const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
  526. // Update the total encoded bits. For temporal layers, update the cumulative
  527. // encoded bits per layer.
  528. for (int i = layer; i < static_cast<int>(cfg_.ts_number_layers); ++i) {
  529. bits_total_[i] += frame_size_in_bits;
  530. }
  531. // Update the most recent pts.
  532. last_pts_ = pkt->data.frame.pts;
  533. ++frame_number_;
  534. ++tot_frame_number_;
  535. }
  536. virtual void EndPassHook(void) {
  537. for (int layer = 0; layer < static_cast<int>(cfg_.ts_number_layers);
  538. ++layer) {
  539. duration_ = (last_pts_ + 1) * timebase_;
  540. if (bits_total_[layer]) {
  541. // Effective file datarate:
  542. effective_datarate_[layer] = (bits_total_[layer] / 1000.0) / duration_;
  543. }
  544. }
  545. }
  546. vpx_codec_pts_t last_pts_;
  547. double timebase_;
  548. int frame_number_; // Counter for number of non-dropped/encoded frames.
  549. int tot_frame_number_; // Counter for total number of input frames.
  550. int64_t bits_total_[3];
  551. double duration_;
  552. double effective_datarate_[3];
  553. int set_cpu_used_;
  554. int64_t bits_in_buffer_model_;
  555. vpx_codec_pts_t first_drop_;
  556. int num_drops_;
  557. int denoiser_on_;
  558. int denoiser_offon_test_;
  559. int denoiser_offon_period_;
  560. int frame_parallel_decoding_mode_;
  561. };
  562. // Check basic rate targeting for VBR mode with 0 lag.
  563. TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagZero) {
  564. cfg_.rc_min_quantizer = 0;
  565. cfg_.rc_max_quantizer = 63;
  566. cfg_.g_error_resilient = 0;
  567. cfg_.rc_end_usage = VPX_VBR;
  568. cfg_.g_lag_in_frames = 0;
  569. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  570. 30, 1, 0, 300);
  571. for (int i = 400; i <= 800; i += 400) {
  572. cfg_.rc_target_bitrate = i;
  573. ResetModel();
  574. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  575. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
  576. << " The datarate for the file is lower than target by too much!";
  577. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
  578. << " The datarate for the file is greater than target by too much!";
  579. }
  580. }
  581. // Check basic rate targeting for VBR mode with non-zero lag.
  582. TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagNonZero) {
  583. cfg_.rc_min_quantizer = 0;
  584. cfg_.rc_max_quantizer = 63;
  585. cfg_.g_error_resilient = 0;
  586. cfg_.rc_end_usage = VPX_VBR;
  587. // For non-zero lag, rate control will work (be within bounds) for
  588. // real-time mode.
  589. if (deadline_ == VPX_DL_REALTIME) {
  590. cfg_.g_lag_in_frames = 15;
  591. } else {
  592. cfg_.g_lag_in_frames = 0;
  593. }
  594. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  595. 30, 1, 0, 300);
  596. for (int i = 400; i <= 800; i += 400) {
  597. cfg_.rc_target_bitrate = i;
  598. ResetModel();
  599. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  600. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
  601. << " The datarate for the file is lower than target by too much!";
  602. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
  603. << " The datarate for the file is greater than target by too much!";
  604. }
  605. }
  606. // Check basic rate targeting for VBR mode with non-zero lag, with
  607. // frame_parallel_decoding_mode off. This enables the adapt_coeff/mode/mv probs
  608. // since error_resilience is off.
  609. TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagNonZeroFrameParDecOff) {
  610. cfg_.rc_min_quantizer = 0;
  611. cfg_.rc_max_quantizer = 63;
  612. cfg_.g_error_resilient = 0;
  613. cfg_.rc_end_usage = VPX_VBR;
  614. // For non-zero lag, rate control will work (be within bounds) for
  615. // real-time mode.
  616. if (deadline_ == VPX_DL_REALTIME) {
  617. cfg_.g_lag_in_frames = 15;
  618. } else {
  619. cfg_.g_lag_in_frames = 0;
  620. }
  621. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  622. 30, 1, 0, 300);
  623. for (int i = 400; i <= 800; i += 400) {
  624. cfg_.rc_target_bitrate = i;
  625. ResetModel();
  626. frame_parallel_decoding_mode_ = 0;
  627. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  628. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
  629. << " The datarate for the file is lower than target by too much!";
  630. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
  631. << " The datarate for the file is greater than target by too much!";
  632. }
  633. }
  634. // Check basic rate targeting for CBR mode.
  635. TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
  636. cfg_.rc_buf_initial_sz = 500;
  637. cfg_.rc_buf_optimal_sz = 500;
  638. cfg_.rc_buf_sz = 1000;
  639. cfg_.rc_dropframe_thresh = 1;
  640. cfg_.rc_min_quantizer = 0;
  641. cfg_.rc_max_quantizer = 63;
  642. cfg_.rc_end_usage = VPX_CBR;
  643. cfg_.g_lag_in_frames = 0;
  644. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  645. 30, 1, 0, 140);
  646. for (int i = 150; i < 800; i += 200) {
  647. cfg_.rc_target_bitrate = i;
  648. ResetModel();
  649. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  650. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  651. << " The datarate for the file is lower than target by too much!";
  652. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
  653. << " The datarate for the file is greater than target by too much!";
  654. }
  655. }
  656. // Check basic rate targeting for CBR mode, with frame_parallel_decoding_mode
  657. // off( and error_resilience off).
  658. TEST_P(DatarateTestVP9Large, BasicRateTargetingFrameParDecOff) {
  659. cfg_.rc_buf_initial_sz = 500;
  660. cfg_.rc_buf_optimal_sz = 500;
  661. cfg_.rc_buf_sz = 1000;
  662. cfg_.rc_dropframe_thresh = 1;
  663. cfg_.rc_min_quantizer = 0;
  664. cfg_.rc_max_quantizer = 63;
  665. cfg_.rc_end_usage = VPX_CBR;
  666. cfg_.g_lag_in_frames = 0;
  667. cfg_.g_error_resilient = 0;
  668. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  669. 30, 1, 0, 140);
  670. for (int i = 150; i < 800; i += 200) {
  671. cfg_.rc_target_bitrate = i;
  672. ResetModel();
  673. frame_parallel_decoding_mode_ = 0;
  674. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  675. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  676. << " The datarate for the file is lower than target by too much!";
  677. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
  678. << " The datarate for the file is greater than target by too much!";
  679. }
  680. }
  681. // Check basic rate targeting for CBR mode, with 2 threads and dropped frames.
  682. TEST_P(DatarateTestVP9Large, BasicRateTargetingDropFramesMultiThreads) {
  683. cfg_.rc_buf_initial_sz = 500;
  684. cfg_.rc_buf_optimal_sz = 500;
  685. cfg_.rc_buf_sz = 1000;
  686. cfg_.rc_dropframe_thresh = 30;
  687. cfg_.rc_min_quantizer = 0;
  688. cfg_.rc_max_quantizer = 63;
  689. cfg_.rc_end_usage = VPX_CBR;
  690. cfg_.g_lag_in_frames = 0;
  691. // Encode using multiple threads.
  692. cfg_.g_threads = 2;
  693. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  694. 30, 1, 0, 140);
  695. cfg_.rc_target_bitrate = 200;
  696. ResetModel();
  697. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  698. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  699. << " The datarate for the file is lower than target by too much!";
  700. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
  701. << " The datarate for the file is greater than target by too much!";
  702. }
  703. // Check basic rate targeting for CBR.
  704. TEST_P(DatarateTestVP9Large, BasicRateTargeting444) {
  705. ::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
  706. cfg_.g_profile = 1;
  707. cfg_.g_timebase = video.timebase();
  708. cfg_.rc_buf_initial_sz = 500;
  709. cfg_.rc_buf_optimal_sz = 500;
  710. cfg_.rc_buf_sz = 1000;
  711. cfg_.rc_dropframe_thresh = 1;
  712. cfg_.rc_min_quantizer = 0;
  713. cfg_.rc_max_quantizer = 63;
  714. cfg_.rc_end_usage = VPX_CBR;
  715. for (int i = 250; i < 900; i += 200) {
  716. cfg_.rc_target_bitrate = i;
  717. ResetModel();
  718. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  719. ASSERT_GE(static_cast<double>(cfg_.rc_target_bitrate),
  720. effective_datarate_[0] * 0.80)
  721. << " The datarate for the file exceeds the target by too much!";
  722. ASSERT_LE(static_cast<double>(cfg_.rc_target_bitrate),
  723. effective_datarate_[0] * 1.15)
  724. << " The datarate for the file missed the target!"
  725. << cfg_.rc_target_bitrate << " " << effective_datarate_;
  726. }
  727. }
  728. // Check that (1) the first dropped frame gets earlier and earlier
  729. // as the drop frame threshold is increased, and (2) that the total number of
  730. // frame drops does not decrease as we increase frame drop threshold.
  731. // Use a lower qp-max to force some frame drops.
  732. TEST_P(DatarateTestVP9Large, ChangingDropFrameThresh) {
  733. cfg_.rc_buf_initial_sz = 500;
  734. cfg_.rc_buf_optimal_sz = 500;
  735. cfg_.rc_buf_sz = 1000;
  736. cfg_.rc_undershoot_pct = 20;
  737. cfg_.rc_undershoot_pct = 20;
  738. cfg_.rc_dropframe_thresh = 10;
  739. cfg_.rc_min_quantizer = 0;
  740. cfg_.rc_max_quantizer = 50;
  741. cfg_.rc_end_usage = VPX_CBR;
  742. cfg_.rc_target_bitrate = 200;
  743. cfg_.g_lag_in_frames = 0;
  744. // TODO(marpan): Investigate datarate target failures with a smaller keyframe
  745. // interval (128).
  746. cfg_.kf_max_dist = 9999;
  747. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  748. 30, 1, 0, 140);
  749. const int kDropFrameThreshTestStep = 30;
  750. for (int j = 50; j <= 150; j += 100) {
  751. cfg_.rc_target_bitrate = j;
  752. vpx_codec_pts_t last_drop = 140;
  753. int last_num_drops = 0;
  754. for (int i = 10; i < 100; i += kDropFrameThreshTestStep) {
  755. cfg_.rc_dropframe_thresh = i;
  756. ResetModel();
  757. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  758. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  759. << " The datarate for the file is lower than target by too much!";
  760. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
  761. << " The datarate for the file is greater than target by too much!";
  762. ASSERT_LE(first_drop_, last_drop)
  763. << " The first dropped frame for drop_thresh " << i
  764. << " > first dropped frame for drop_thresh "
  765. << i - kDropFrameThreshTestStep;
  766. ASSERT_GE(num_drops_, last_num_drops * 0.85)
  767. << " The number of dropped frames for drop_thresh " << i
  768. << " < number of dropped frames for drop_thresh "
  769. << i - kDropFrameThreshTestStep;
  770. last_drop = first_drop_;
  771. last_num_drops = num_drops_;
  772. }
  773. }
  774. }
  775. // Check basic rate targeting for 2 temporal layers.
  776. TEST_P(DatarateTestVP9Large, BasicRateTargeting2TemporalLayers) {
  777. cfg_.rc_buf_initial_sz = 500;
  778. cfg_.rc_buf_optimal_sz = 500;
  779. cfg_.rc_buf_sz = 1000;
  780. cfg_.rc_dropframe_thresh = 1;
  781. cfg_.rc_min_quantizer = 0;
  782. cfg_.rc_max_quantizer = 63;
  783. cfg_.rc_end_usage = VPX_CBR;
  784. cfg_.g_lag_in_frames = 0;
  785. // 2 Temporal layers, no spatial layers: Framerate decimation (2, 1).
  786. cfg_.ss_number_layers = 1;
  787. cfg_.ts_number_layers = 2;
  788. cfg_.ts_rate_decimator[0] = 2;
  789. cfg_.ts_rate_decimator[1] = 1;
  790. cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
  791. if (deadline_ == VPX_DL_REALTIME) cfg_.g_error_resilient = 1;
  792. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  793. 30, 1, 0, 200);
  794. for (int i = 200; i <= 800; i += 200) {
  795. cfg_.rc_target_bitrate = i;
  796. ResetModel();
  797. // 60-40 bitrate allocation for 2 temporal layers.
  798. cfg_.layer_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
  799. cfg_.layer_target_bitrate[1] = cfg_.rc_target_bitrate;
  800. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  801. for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
  802. ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
  803. << " The datarate for the file is lower than target by too much, "
  804. "for layer: "
  805. << j;
  806. ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
  807. << " The datarate for the file is greater than target by too much, "
  808. "for layer: "
  809. << j;
  810. }
  811. }
  812. }
  813. // Check basic rate targeting for 3 temporal layers.
  814. TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayers) {
  815. cfg_.rc_buf_initial_sz = 500;
  816. cfg_.rc_buf_optimal_sz = 500;
  817. cfg_.rc_buf_sz = 1000;
  818. cfg_.rc_dropframe_thresh = 1;
  819. cfg_.rc_min_quantizer = 0;
  820. cfg_.rc_max_quantizer = 63;
  821. cfg_.rc_end_usage = VPX_CBR;
  822. cfg_.g_lag_in_frames = 0;
  823. // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
  824. cfg_.ss_number_layers = 1;
  825. cfg_.ts_number_layers = 3;
  826. cfg_.ts_rate_decimator[0] = 4;
  827. cfg_.ts_rate_decimator[1] = 2;
  828. cfg_.ts_rate_decimator[2] = 1;
  829. cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
  830. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  831. 30, 1, 0, 200);
  832. for (int i = 200; i <= 800; i += 200) {
  833. cfg_.rc_target_bitrate = i;
  834. ResetModel();
  835. // 40-20-40 bitrate allocation for 3 temporal layers.
  836. cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
  837. cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
  838. cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
  839. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  840. for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
  841. // TODO(yaowu): Work out more stable rc control strategy and
  842. // Adjust the thresholds to be tighter than .75.
  843. ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.75)
  844. << " The datarate for the file is lower than target by too much, "
  845. "for layer: "
  846. << j;
  847. // TODO(yaowu): Work out more stable rc control strategy and
  848. // Adjust the thresholds to be tighter than 1.25.
  849. ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.25)
  850. << " The datarate for the file is greater than target by too much, "
  851. "for layer: "
  852. << j;
  853. }
  854. }
  855. }
  856. // Check basic rate targeting for 3 temporal layers, with frame dropping.
  857. // Only for one (low) bitrate with lower max_quantizer, and somewhat higher
  858. // frame drop threshold, to force frame dropping.
  859. TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayersFrameDropping) {
  860. cfg_.rc_buf_initial_sz = 500;
  861. cfg_.rc_buf_optimal_sz = 500;
  862. cfg_.rc_buf_sz = 1000;
  863. // Set frame drop threshold and rc_max_quantizer to force some frame drops.
  864. cfg_.rc_dropframe_thresh = 20;
  865. cfg_.rc_max_quantizer = 45;
  866. cfg_.rc_min_quantizer = 0;
  867. cfg_.rc_end_usage = VPX_CBR;
  868. cfg_.g_lag_in_frames = 0;
  869. // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
  870. cfg_.ss_number_layers = 1;
  871. cfg_.ts_number_layers = 3;
  872. cfg_.ts_rate_decimator[0] = 4;
  873. cfg_.ts_rate_decimator[1] = 2;
  874. cfg_.ts_rate_decimator[2] = 1;
  875. cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
  876. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  877. 30, 1, 0, 200);
  878. cfg_.rc_target_bitrate = 200;
  879. ResetModel();
  880. // 40-20-40 bitrate allocation for 3 temporal layers.
  881. cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
  882. cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
  883. cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
  884. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  885. for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
  886. ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
  887. << " The datarate for the file is lower than target by too much, "
  888. "for layer: "
  889. << j;
  890. ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
  891. << " The datarate for the file is greater than target by too much, "
  892. "for layer: "
  893. << j;
  894. // Expect some frame drops in this test: for this 200 frames test,
  895. // expect at least 10% and not more than 60% drops.
  896. ASSERT_GE(num_drops_, 20);
  897. ASSERT_LE(num_drops_, 130);
  898. }
  899. }
  900. #if CONFIG_VP9_TEMPORAL_DENOISING
  901. class DatarateTestVP9LargeDenoiser : public DatarateTestVP9Large {
  902. public:
  903. virtual ~DatarateTestVP9LargeDenoiser() {}
  904. };
  905. // Check basic datarate targeting, for a single bitrate, when denoiser is on.
  906. TEST_P(DatarateTestVP9LargeDenoiser, LowNoise) {
  907. cfg_.rc_buf_initial_sz = 500;
  908. cfg_.rc_buf_optimal_sz = 500;
  909. cfg_.rc_buf_sz = 1000;
  910. cfg_.rc_dropframe_thresh = 1;
  911. cfg_.rc_min_quantizer = 2;
  912. cfg_.rc_max_quantizer = 56;
  913. cfg_.rc_end_usage = VPX_CBR;
  914. cfg_.g_lag_in_frames = 0;
  915. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  916. 30, 1, 0, 140);
  917. // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
  918. // there is only one denoiser mode: denoiserYonly(which is 1),
  919. // but may add more modes in the future.
  920. cfg_.rc_target_bitrate = 300;
  921. ResetModel();
  922. // Turn on the denoiser.
  923. denoiser_on_ = 1;
  924. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  925. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  926. << " The datarate for the file is lower than target by too much!";
  927. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
  928. << " The datarate for the file is greater than target by too much!";
  929. }
  930. // Check basic datarate targeting, for a single bitrate, when denoiser is on,
  931. // for clip with high noise level. Use 2 threads.
  932. TEST_P(DatarateTestVP9LargeDenoiser, HighNoise) {
  933. cfg_.rc_buf_initial_sz = 500;
  934. cfg_.rc_buf_optimal_sz = 500;
  935. cfg_.rc_buf_sz = 1000;
  936. cfg_.rc_dropframe_thresh = 1;
  937. cfg_.rc_min_quantizer = 2;
  938. cfg_.rc_max_quantizer = 56;
  939. cfg_.rc_end_usage = VPX_CBR;
  940. cfg_.g_lag_in_frames = 0;
  941. cfg_.g_threads = 2;
  942. ::libvpx_test::Y4mVideoSource video("noisy_clip_640_360.y4m", 0, 200);
  943. // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
  944. // there is only one denoiser mode: kDenoiserOnYOnly(which is 1),
  945. // but may add more modes in the future.
  946. cfg_.rc_target_bitrate = 1000;
  947. ResetModel();
  948. // Turn on the denoiser.
  949. denoiser_on_ = 1;
  950. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  951. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  952. << " The datarate for the file is lower than target by too much!";
  953. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
  954. << " The datarate for the file is greater than target by too much!";
  955. }
  956. // Check basic datarate targeting, for a single bitrate, when denoiser is on,
  957. // for 1280x720 clip with 4 threads.
  958. TEST_P(DatarateTestVP9LargeDenoiser, 4threads) {
  959. cfg_.rc_buf_initial_sz = 500;
  960. cfg_.rc_buf_optimal_sz = 500;
  961. cfg_.rc_buf_sz = 1000;
  962. cfg_.rc_dropframe_thresh = 1;
  963. cfg_.rc_min_quantizer = 2;
  964. cfg_.rc_max_quantizer = 56;
  965. cfg_.rc_end_usage = VPX_CBR;
  966. cfg_.g_lag_in_frames = 0;
  967. cfg_.g_threads = 4;
  968. ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
  969. // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
  970. // there is only one denoiser mode: denoiserYonly(which is 1),
  971. // but may add more modes in the future.
  972. cfg_.rc_target_bitrate = 1000;
  973. ResetModel();
  974. // Turn on the denoiser.
  975. denoiser_on_ = 1;
  976. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  977. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  978. << " The datarate for the file is lower than target by too much!";
  979. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.29)
  980. << " The datarate for the file is greater than target by too much!";
  981. }
  982. // Check basic datarate targeting, for a single bitrate, when denoiser is off
  983. // and on.
  984. TEST_P(DatarateTestVP9LargeDenoiser, DenoiserOffOn) {
  985. cfg_.rc_buf_initial_sz = 500;
  986. cfg_.rc_buf_optimal_sz = 500;
  987. cfg_.rc_buf_sz = 1000;
  988. cfg_.rc_dropframe_thresh = 1;
  989. cfg_.rc_min_quantizer = 2;
  990. cfg_.rc_max_quantizer = 56;
  991. cfg_.rc_end_usage = VPX_CBR;
  992. cfg_.g_lag_in_frames = 0;
  993. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  994. 30, 1, 0, 299);
  995. // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
  996. // there is only one denoiser mode: denoiserYonly(which is 1),
  997. // but may add more modes in the future.
  998. cfg_.rc_target_bitrate = 300;
  999. ResetModel();
  1000. // The denoiser is off by default.
  1001. denoiser_on_ = 0;
  1002. // Set the offon test flag.
  1003. denoiser_offon_test_ = 1;
  1004. denoiser_offon_period_ = 100;
  1005. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  1006. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  1007. << " The datarate for the file is lower than target by too much!";
  1008. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
  1009. << " The datarate for the file is greater than target by too much!";
  1010. }
  1011. #endif // CONFIG_VP9_TEMPORAL_DENOISING
  1012. class DatarateOnePassCbrSvc
  1013. : public ::libvpx_test::EncoderTest,
  1014. public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
  1015. public:
  1016. DatarateOnePassCbrSvc() : EncoderTest(GET_PARAM(0)) {
  1017. memset(&svc_params_, 0, sizeof(svc_params_));
  1018. }
  1019. virtual ~DatarateOnePassCbrSvc() {}
  1020. protected:
  1021. virtual void SetUp() {
  1022. InitializeConfig();
  1023. SetMode(GET_PARAM(1));
  1024. speed_setting_ = GET_PARAM(2);
  1025. ResetModel();
  1026. }
  1027. virtual void ResetModel() {
  1028. last_pts_ = 0;
  1029. bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
  1030. frame_number_ = 0;
  1031. first_drop_ = 0;
  1032. bits_total_ = 0;
  1033. duration_ = 0.0;
  1034. mismatch_psnr_ = 0.0;
  1035. mismatch_nframes_ = 0;
  1036. denoiser_on_ = 0;
  1037. tune_content_ = 0;
  1038. base_speed_setting_ = 5;
  1039. }
  1040. virtual void BeginPassHook(unsigned int /*pass*/) {}
  1041. virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
  1042. ::libvpx_test::Encoder *encoder) {
  1043. if (video->frame() == 0) {
  1044. int i;
  1045. for (i = 0; i < VPX_MAX_LAYERS; ++i) {
  1046. svc_params_.max_quantizers[i] = 63;
  1047. svc_params_.min_quantizers[i] = 0;
  1048. }
  1049. svc_params_.speed_per_layer[0] = base_speed_setting_;
  1050. for (i = 1; i < VPX_SS_MAX_LAYERS; ++i) {
  1051. svc_params_.speed_per_layer[i] = speed_setting_;
  1052. }
  1053. encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
  1054. encoder->Control(VP9E_SET_SVC, 1);
  1055. encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_);
  1056. encoder->Control(VP8E_SET_CPUUSED, speed_setting_);
  1057. encoder->Control(VP9E_SET_TILE_COLUMNS, 0);
  1058. encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 300);
  1059. encoder->Control(VP9E_SET_TILE_COLUMNS, (cfg_.g_threads >> 1));
  1060. encoder->Control(VP9E_SET_ROW_MT, 1);
  1061. encoder->Control(VP8E_SET_STATIC_THRESHOLD, 1);
  1062. encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_);
  1063. }
  1064. const vpx_rational_t tb = video->timebase();
  1065. timebase_ = static_cast<double>(tb.num) / tb.den;
  1066. duration_ = 0;
  1067. }
  1068. virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
  1069. vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
  1070. if (last_pts_ == 0) duration = 1;
  1071. bits_in_buffer_model_ += static_cast<int64_t>(
  1072. duration * timebase_ * cfg_.rc_target_bitrate * 1000);
  1073. const bool key_frame =
  1074. (pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
  1075. if (!key_frame) {
  1076. // TODO(marpan): This check currently fails for some of the SVC tests,
  1077. // re-enable when issue (webm:1350) is resolved.
  1078. // ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
  1079. // << pkt->data.frame.pts;
  1080. }
  1081. const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
  1082. bits_in_buffer_model_ -= static_cast<int64_t>(frame_size_in_bits);
  1083. bits_total_ += frame_size_in_bits;
  1084. if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1;
  1085. last_pts_ = pkt->data.frame.pts;
  1086. bits_in_last_frame_ = frame_size_in_bits;
  1087. ++frame_number_;
  1088. }
  1089. virtual void EndPassHook(void) {
  1090. if (bits_total_) {
  1091. const double file_size_in_kb = bits_total_ / 1000.; // bits per kilobit
  1092. duration_ = (last_pts_ + 1) * timebase_;
  1093. file_datarate_ = file_size_in_kb / duration_;
  1094. }
  1095. }
  1096. virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
  1097. double mismatch_psnr = compute_psnr(img1, img2);
  1098. mismatch_psnr_ += mismatch_psnr;
  1099. ++mismatch_nframes_;
  1100. }
  1101. unsigned int GetMismatchFrames() { return mismatch_nframes_; }
  1102. vpx_codec_pts_t last_pts_;
  1103. int64_t bits_in_buffer_model_;
  1104. double timebase_;
  1105. int frame_number_;
  1106. vpx_codec_pts_t first_drop_;
  1107. int64_t bits_total_;
  1108. double duration_;
  1109. double file_datarate_;
  1110. size_t bits_in_last_frame_;
  1111. vpx_svc_extra_cfg_t svc_params_;
  1112. int speed_setting_;
  1113. double mismatch_psnr_;
  1114. int mismatch_nframes_;
  1115. int denoiser_on_;
  1116. int tune_content_;
  1117. int base_speed_setting_;
  1118. };
  1119. static void assign_layer_bitrates(vpx_codec_enc_cfg_t *const enc_cfg,
  1120. const vpx_svc_extra_cfg_t *svc_params,
  1121. int spatial_layers, int temporal_layers,
  1122. int temporal_layering_mode) {
  1123. int sl, spatial_layer_target;
  1124. float total = 0;
  1125. float alloc_ratio[VPX_MAX_LAYERS] = { 0 };
  1126. for (sl = 0; sl < spatial_layers; ++sl) {
  1127. if (svc_params->scaling_factor_den[sl] > 0) {
  1128. alloc_ratio[sl] = (float)(svc_params->scaling_factor_num[sl] * 1.0 /
  1129. svc_params->scaling_factor_den[sl]);
  1130. total += alloc_ratio[sl];
  1131. }
  1132. }
  1133. for (sl = 0; sl < spatial_layers; ++sl) {
  1134. enc_cfg->ss_target_bitrate[sl] = spatial_layer_target =
  1135. (unsigned int)(enc_cfg->rc_target_bitrate * alloc_ratio[sl] / total);
  1136. const int index = sl * temporal_layers;
  1137. if (temporal_layering_mode == 3) {
  1138. enc_cfg->layer_target_bitrate[index] = spatial_layer_target >> 1;
  1139. enc_cfg->layer_target_bitrate[index + 1] =
  1140. (spatial_layer_target >> 1) + (spatial_layer_target >> 2);
  1141. enc_cfg->layer_target_bitrate[index + 2] = spatial_layer_target;
  1142. } else if (temporal_layering_mode == 2) {
  1143. enc_cfg->layer_target_bitrate[index] = spatial_layer_target * 2 / 3;
  1144. enc_cfg->layer_target_bitrate[index + 1] = spatial_layer_target;
  1145. }
  1146. }
  1147. }
  1148. // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 1
  1149. // temporal layer, with screen content mode on and same speed setting for all
  1150. // layers.
  1151. TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL1TLScreenContent1) {
  1152. cfg_.rc_buf_initial_sz = 500;
  1153. cfg_.rc_buf_optimal_sz = 500;
  1154. cfg_.rc_buf_sz = 1000;
  1155. cfg_.rc_min_quantizer = 0;
  1156. cfg_.rc_max_quantizer = 63;
  1157. cfg_.rc_end_usage = VPX_CBR;
  1158. cfg_.g_lag_in_frames = 0;
  1159. cfg_.ss_number_layers = 2;
  1160. cfg_.ts_number_layers = 1;
  1161. cfg_.ts_rate_decimator[0] = 1;
  1162. cfg_.g_error_resilient = 1;
  1163. cfg_.g_threads = 1;
  1164. cfg_.temporal_layering_mode = 0;
  1165. svc_params_.scaling_factor_num[0] = 144;
  1166. svc_params_.scaling_factor_den[0] = 288;
  1167. svc_params_.scaling_factor_num[1] = 288;
  1168. svc_params_.scaling_factor_den[1] = 288;
  1169. cfg_.rc_dropframe_thresh = 10;
  1170. cfg_.kf_max_dist = 9999;
  1171. ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
  1172. cfg_.rc_target_bitrate = 500;
  1173. ResetModel();
  1174. tune_content_ = 1;
  1175. base_speed_setting_ = speed_setting_;
  1176. assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
  1177. cfg_.ts_number_layers, cfg_.temporal_layering_mode);
  1178. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  1179. EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
  1180. }
  1181. // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
  1182. // 3 temporal layers. Run CIF clip with 1 thread.
  1183. TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL3TL) {
  1184. cfg_.rc_buf_initial_sz = 500;
  1185. cfg_.rc_buf_optimal_sz = 500;
  1186. cfg_.rc_buf_sz = 1000;
  1187. cfg_.rc_min_quantizer = 0;
  1188. cfg_.rc_max_quantizer = 63;
  1189. cfg_.rc_end_usage = VPX_CBR;
  1190. cfg_.g_lag_in_frames = 0;
  1191. cfg_.ss_number_layers = 2;
  1192. cfg_.ts_number_layers = 3;
  1193. cfg_.ts_rate_decimator[0] = 4;
  1194. cfg_.ts_rate_decimator[1] = 2;
  1195. cfg_.ts_rate_decimator[2] = 1;
  1196. cfg_.g_error_resilient = 1;
  1197. cfg_.g_threads = 1;
  1198. cfg_.temporal_layering_mode = 3;
  1199. svc_params_.scaling_factor_num[0] = 144;
  1200. svc_params_.scaling_factor_den[0] = 288;
  1201. svc_params_.scaling_factor_num[1] = 288;
  1202. svc_params_.scaling_factor_den[1] = 288;
  1203. cfg_.rc_dropframe_thresh = 0;
  1204. cfg_.kf_max_dist = 9999;
  1205. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  1206. 30, 1, 0, 200);
  1207. // TODO(marpan): Check that effective_datarate for each layer hits the
  1208. // layer target_bitrate.
  1209. for (int i = 200; i <= 800; i += 200) {
  1210. cfg_.rc_target_bitrate = i;
  1211. ResetModel();
  1212. assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
  1213. cfg_.ts_number_layers, cfg_.temporal_layering_mode);
  1214. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  1215. ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
  1216. << " The datarate for the file exceeds the target by too much!";
  1217. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
  1218. << " The datarate for the file is lower than the target by too much!";
  1219. #if CONFIG_VP9_DECODER
  1220. // Number of temporal layers > 1, so half of the frames in this SVC pattern
  1221. // will be non-reference frame and hence encoder will avoid loopfilter.
  1222. // Since frame dropper is off, we can expcet 100 (half of the sequence)
  1223. // mismatched frames.
  1224. EXPECT_EQ(static_cast<unsigned int>(100), GetMismatchFrames());
  1225. #endif
  1226. }
  1227. }
  1228. // Check basic rate targeting for 1 pass CBR SVC with denoising.
  1229. // 2 spatial layers and 3 temporal layer. Run HD clip with 2 threads.
  1230. TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL3TLDenoiserOn) {
  1231. cfg_.rc_buf_initial_sz = 500;
  1232. cfg_.rc_buf_optimal_sz = 500;
  1233. cfg_.rc_buf_sz = 1000;
  1234. cfg_.rc_min_quantizer = 0;
  1235. cfg_.rc_max_quantizer = 63;
  1236. cfg_.rc_end_usage = VPX_CBR;
  1237. cfg_.g_lag_in_frames = 0;
  1238. cfg_.ss_number_layers = 2;
  1239. cfg_.ts_number_layers = 3;
  1240. cfg_.ts_rate_decimator[0] = 4;
  1241. cfg_.ts_rate_decimator[1] = 2;
  1242. cfg_.ts_rate_decimator[2] = 1;
  1243. cfg_.g_error_resilient = 1;
  1244. cfg_.g_threads = 2;
  1245. cfg_.temporal_layering_mode = 3;
  1246. svc_params_.scaling_factor_num[0] = 144;
  1247. svc_params_.scaling_factor_den[0] = 288;
  1248. svc_params_.scaling_factor_num[1] = 288;
  1249. svc_params_.scaling_factor_den[1] = 288;
  1250. cfg_.rc_dropframe_thresh = 0;
  1251. cfg_.kf_max_dist = 9999;
  1252. ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
  1253. // TODO(marpan): Check that effective_datarate for each layer hits the
  1254. // layer target_bitrate.
  1255. for (int i = 600; i <= 1000; i += 200) {
  1256. cfg_.rc_target_bitrate = i;
  1257. ResetModel();
  1258. denoiser_on_ = 1;
  1259. assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
  1260. cfg_.ts_number_layers, cfg_.temporal_layering_mode);
  1261. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  1262. ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
  1263. << " The datarate for the file exceeds the target by too much!";
  1264. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
  1265. << " The datarate for the file is lower than the target by too much!";
  1266. #if CONFIG_VP9_DECODER
  1267. // Number of temporal layers > 1, so half of the frames in this SVC pattern
  1268. // will be non-reference frame and hence encoder will avoid loopfilter.
  1269. // Since frame dropper is off, we can expcet 150 (half of the sequence)
  1270. // mismatched frames.
  1271. EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
  1272. #endif
  1273. }
  1274. }
  1275. // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 3
  1276. // temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
  1277. TEST_P(DatarateOnePassCbrSvc, DISABLED_OnePassCbrSvc2SL3TLSmallKf) {
  1278. cfg_.rc_buf_initial_sz = 500;
  1279. cfg_.rc_buf_optimal_sz = 500;
  1280. cfg_.rc_buf_sz = 1000;
  1281. cfg_.rc_min_quantizer = 0;
  1282. cfg_.rc_max_quantizer = 63;
  1283. cfg_.rc_end_usage = VPX_CBR;
  1284. cfg_.g_lag_in_frames = 0;
  1285. cfg_.ss_number_layers = 2;
  1286. cfg_.ts_number_layers = 3;
  1287. cfg_.ts_rate_decimator[0] = 4;
  1288. cfg_.ts_rate_decimator[1] = 2;
  1289. cfg_.ts_rate_decimator[2] = 1;
  1290. cfg_.g_error_resilient = 1;
  1291. cfg_.g_threads = 1;
  1292. cfg_.temporal_layering_mode = 3;
  1293. svc_params_.scaling_factor_num[0] = 144;
  1294. svc_params_.scaling_factor_den[0] = 288;
  1295. svc_params_.scaling_factor_num[1] = 288;
  1296. svc_params_.scaling_factor_den[1] = 288;
  1297. cfg_.rc_dropframe_thresh = 10;
  1298. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  1299. 30, 1, 0, 200);
  1300. cfg_.rc_target_bitrate = 400;
  1301. // For this 3 temporal layer case, pattern repeats every 4 frames, so choose
  1302. // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
  1303. for (int j = 64; j <= 67; j++) {
  1304. cfg_.kf_max_dist = j;
  1305. ResetModel();
  1306. assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
  1307. cfg_.ts_number_layers, cfg_.temporal_layering_mode);
  1308. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  1309. ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.80)
  1310. << " The datarate for the file exceeds the target by too much!";
  1311. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
  1312. << " The datarate for the file is lower than the target by too much!";
  1313. }
  1314. }
  1315. // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
  1316. // 3 temporal layers. Run HD clip with 4 threads.
  1317. TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL3TL4Threads) {
  1318. cfg_.rc_buf_initial_sz = 500;
  1319. cfg_.rc_buf_optimal_sz = 500;
  1320. cfg_.rc_buf_sz = 1000;
  1321. cfg_.rc_min_quantizer = 0;
  1322. cfg_.rc_max_quantizer = 63;
  1323. cfg_.rc_end_usage = VPX_CBR;
  1324. cfg_.g_lag_in_frames = 0;
  1325. cfg_.ss_number_layers = 2;
  1326. cfg_.ts_number_layers = 3;
  1327. cfg_.ts_rate_decimator[0] = 4;
  1328. cfg_.ts_rate_decimator[1] = 2;
  1329. cfg_.ts_rate_decimator[2] = 1;
  1330. cfg_.g_error_resilient = 1;
  1331. cfg_.g_threads = 4;
  1332. cfg_.temporal_layering_mode = 3;
  1333. svc_params_.scaling_factor_num[0] = 144;
  1334. svc_params_.scaling_factor_den[0] = 288;
  1335. svc_params_.scaling_factor_num[1] = 288;
  1336. svc_params_.scaling_factor_den[1] = 288;
  1337. cfg_.rc_dropframe_thresh = 0;
  1338. cfg_.kf_max_dist = 9999;
  1339. ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
  1340. cfg_.rc_target_bitrate = 800;
  1341. ResetModel();
  1342. assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
  1343. cfg_.ts_number_layers, cfg_.temporal_layering_mode);
  1344. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  1345. ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
  1346. << " The datarate for the file exceeds the target by too much!";
  1347. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
  1348. << " The datarate for the file is lower than the target by too much!";
  1349. #if CONFIG_VP9_DECODER
  1350. // Number of temporal layers > 1, so half of the frames in this SVC pattern
  1351. // will be non-reference frame and hence encoder will avoid loopfilter.
  1352. // Since frame dropper is off, we can expcet 150 (half of the sequence)
  1353. // mismatched frames.
  1354. EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
  1355. #endif
  1356. }
  1357. // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
  1358. // 3 temporal layers. Run CIF clip with 1 thread.
  1359. TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SL3TL) {
  1360. cfg_.rc_buf_initial_sz = 500;
  1361. cfg_.rc_buf_optimal_sz = 500;
  1362. cfg_.rc_buf_sz = 1000;
  1363. cfg_.rc_min_quantizer = 0;
  1364. cfg_.rc_max_quantizer = 63;
  1365. cfg_.rc_end_usage = VPX_CBR;
  1366. cfg_.g_lag_in_frames = 0;
  1367. cfg_.ss_number_layers = 3;
  1368. cfg_.ts_number_layers = 3;
  1369. cfg_.ts_rate_decimator[0] = 4;
  1370. cfg_.ts_rate_decimator[1] = 2;
  1371. cfg_.ts_rate_decimator[2] = 1;
  1372. cfg_.g_error_resilient = 1;
  1373. cfg_.g_threads = 1;
  1374. cfg_.temporal_layering_mode = 3;
  1375. svc_params_.scaling_factor_num[0] = 72;
  1376. svc_params_.scaling_factor_den[0] = 288;
  1377. svc_params_.scaling_factor_num[1] = 144;
  1378. svc_params_.scaling_factor_den[1] = 288;
  1379. svc_params_.scaling_factor_num[2] = 288;
  1380. svc_params_.scaling_factor_den[2] = 288;
  1381. cfg_.rc_dropframe_thresh = 0;
  1382. cfg_.kf_max_dist = 9999;
  1383. ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
  1384. cfg_.rc_target_bitrate = 800;
  1385. ResetModel();
  1386. assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
  1387. cfg_.ts_number_layers, cfg_.temporal_layering_mode);
  1388. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  1389. ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
  1390. << " The datarate for the file exceeds the target by too much!";
  1391. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22)
  1392. << " The datarate for the file is lower than the target by too much!";
  1393. #if CONFIG_VP9_DECODER
  1394. // Number of temporal layers > 1, so half of the frames in this SVC pattern
  1395. // will be non-reference frame and hence encoder will avoid loopfilter.
  1396. // Since frame dropper is off, we can expcet 150 (half of the sequence)
  1397. // mismatched frames.
  1398. EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
  1399. #endif
  1400. }
  1401. // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
  1402. // temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
  1403. TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SL3TLSmallKf) {
  1404. cfg_.rc_buf_initial_sz = 500;
  1405. cfg_.rc_buf_optimal_sz = 500;
  1406. cfg_.rc_buf_sz = 1000;
  1407. cfg_.rc_min_quantizer = 0;
  1408. cfg_.rc_max_quantizer = 63;
  1409. cfg_.rc_end_usage = VPX_CBR;
  1410. cfg_.g_lag_in_frames = 0;
  1411. cfg_.ss_number_layers = 3;
  1412. cfg_.ts_number_layers = 3;
  1413. cfg_.ts_rate_decimator[0] = 4;
  1414. cfg_.ts_rate_decimator[1] = 2;
  1415. cfg_.ts_rate_decimator[2] = 1;
  1416. cfg_.g_error_resilient = 1;
  1417. cfg_.g_threads = 1;
  1418. cfg_.temporal_layering_mode = 3;
  1419. svc_params_.scaling_factor_num[0] = 72;
  1420. svc_params_.scaling_factor_den[0] = 288;
  1421. svc_params_.scaling_factor_num[1] = 144;
  1422. svc_params_.scaling_factor_den[1] = 288;
  1423. svc_params_.scaling_factor_num[2] = 288;
  1424. svc_params_.scaling_factor_den[2] = 288;
  1425. cfg_.rc_dropframe_thresh = 10;
  1426. ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
  1427. cfg_.rc_target_bitrate = 800;
  1428. // For this 3 temporal layer case, pattern repeats every 4 frames, so choose
  1429. // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
  1430. for (int j = 32; j <= 35; j++) {
  1431. cfg_.kf_max_dist = j;
  1432. ResetModel();
  1433. assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
  1434. cfg_.ts_number_layers, cfg_.temporal_layering_mode);
  1435. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  1436. ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.80)
  1437. << " The datarate for the file exceeds the target by too much!";
  1438. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.30)
  1439. << " The datarate for the file is lower than the target by too much!";
  1440. }
  1441. }
  1442. // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
  1443. // 3 temporal layers. Run HD clip with 4 threads.
  1444. TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SL3TL4threads) {
  1445. cfg_.rc_buf_initial_sz = 500;
  1446. cfg_.rc_buf_optimal_sz = 500;
  1447. cfg_.rc_buf_sz = 1000;
  1448. cfg_.rc_min_quantizer = 0;
  1449. cfg_.rc_max_quantizer = 63;
  1450. cfg_.rc_end_usage = VPX_CBR;
  1451. cfg_.g_lag_in_frames = 0;
  1452. cfg_.ss_number_layers = 3;
  1453. cfg_.ts_number_layers = 3;
  1454. cfg_.ts_rate_decimator[0] = 4;
  1455. cfg_.ts_rate_decimator[1] = 2;
  1456. cfg_.ts_rate_decimator[2] = 1;
  1457. cfg_.g_error_resilient = 1;
  1458. cfg_.g_threads = 4;
  1459. cfg_.temporal_layering_mode = 3;
  1460. svc_params_.scaling_factor_num[0] = 72;
  1461. svc_params_.scaling_factor_den[0] = 288;
  1462. svc_params_.scaling_factor_num[1] = 144;
  1463. svc_params_.scaling_factor_den[1] = 288;
  1464. svc_params_.scaling_factor_num[2] = 288;
  1465. svc_params_.scaling_factor_den[2] = 288;
  1466. cfg_.rc_dropframe_thresh = 0;
  1467. cfg_.kf_max_dist = 9999;
  1468. ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
  1469. cfg_.rc_target_bitrate = 800;
  1470. ResetModel();
  1471. assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
  1472. cfg_.ts_number_layers, cfg_.temporal_layering_mode);
  1473. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  1474. ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
  1475. << " The datarate for the file exceeds the target by too much!";
  1476. ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22)
  1477. << " The datarate for the file is lower than the target by too much!";
  1478. #if CONFIG_VP9_DECODER
  1479. // Number of temporal layers > 1, so half of the frames in this SVC pattern
  1480. // will be non-reference frame and hence encoder will avoid loopfilter.
  1481. // Since frame dropper is off, we can expcet 150 (half of the sequence)
  1482. // mismatched frames.
  1483. EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
  1484. #endif
  1485. }
  1486. // Run SVC encoder for 1 temporal layer, 2 spatial layers, with spatial
  1487. // downscale 5x5.
  1488. TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL1TL5x5MultipleRuns) {
  1489. cfg_.rc_buf_initial_sz = 500;
  1490. cfg_.rc_buf_optimal_sz = 500;
  1491. cfg_.rc_buf_sz = 1000;
  1492. cfg_.rc_min_quantizer = 0;
  1493. cfg_.rc_max_quantizer = 63;
  1494. cfg_.rc_end_usage = VPX_CBR;
  1495. cfg_.g_lag_in_frames = 0;
  1496. cfg_.ss_number_layers = 2;
  1497. cfg_.ts_number_layers = 1;
  1498. cfg_.ts_rate_decimator[0] = 1;
  1499. cfg_.g_error_resilient = 1;
  1500. cfg_.g_threads = 3;
  1501. cfg_.temporal_layering_mode = 0;
  1502. svc_params_.scaling_factor_num[0] = 256;
  1503. svc_params_.scaling_factor_den[0] = 1280;
  1504. svc_params_.scaling_factor_num[1] = 1280;
  1505. svc_params_.scaling_factor_den[1] = 1280;
  1506. cfg_.rc_dropframe_thresh = 10;
  1507. cfg_.kf_max_dist = 999999;
  1508. cfg_.kf_min_dist = 0;
  1509. cfg_.ss_target_bitrate[0] = 300;
  1510. cfg_.ss_target_bitrate[1] = 1400;
  1511. cfg_.layer_target_bitrate[0] = 300;
  1512. cfg_.layer_target_bitrate[1] = 1400;
  1513. cfg_.rc_target_bitrate = 1700;
  1514. ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
  1515. ResetModel();
  1516. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  1517. EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
  1518. }
  1519. VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES,
  1520. ::testing::Values(0));
  1521. VP8_INSTANTIATE_TEST_CASE(DatarateTestRealTime,
  1522. ::testing::Values(::libvpx_test::kRealTime),
  1523. ::testing::Values(-6, -12));
  1524. VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large,
  1525. ::testing::Values(::libvpx_test::kOnePassGood,
  1526. ::libvpx_test::kRealTime),
  1527. ::testing::Range(2, 9));
  1528. #if CONFIG_VP9_TEMPORAL_DENOISING
  1529. VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9LargeDenoiser,
  1530. ::testing::Values(::libvpx_test::kRealTime),
  1531. ::testing::Range(5, 9));
  1532. #endif
  1533. VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvc,
  1534. ::testing::Values(::libvpx_test::kRealTime),
  1535. ::testing::Range(5, 9));
  1536. } // namespace