vp9_datarate_test.cc 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901
  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. #include "vpx_ports/bitops.h"
  19. namespace {
  20. class DatarateTestVP9 : public ::libvpx_test::EncoderTest {
  21. public:
  22. explicit DatarateTestVP9(const ::libvpx_test::CodecFactory *codec)
  23. : EncoderTest(codec) {
  24. tune_content_ = 0;
  25. }
  26. protected:
  27. virtual ~DatarateTestVP9() {}
  28. virtual void ResetModel() {
  29. last_pts_ = 0;
  30. bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
  31. frame_number_ = 0;
  32. tot_frame_number_ = 0;
  33. first_drop_ = 0;
  34. num_drops_ = 0;
  35. aq_mode_ = 3;
  36. // Denoiser is off by default.
  37. denoiser_on_ = 0;
  38. // For testing up to 3 layers.
  39. for (int i = 0; i < 3; ++i) {
  40. bits_total_[i] = 0;
  41. }
  42. denoiser_offon_test_ = 0;
  43. denoiser_offon_period_ = -1;
  44. frame_parallel_decoding_mode_ = 1;
  45. use_roi_ = false;
  46. }
  47. //
  48. // Frame flags and layer id for temporal layers.
  49. //
  50. // For two layers, test pattern is:
  51. // 1 3
  52. // 0 2 .....
  53. // For three layers, test pattern is:
  54. // 1 3 5 7
  55. // 2 6
  56. // 0 4 ....
  57. // LAST is always update on base/layer 0, GOLDEN is updated on layer 1.
  58. // For this 3 layer example, the 2nd enhancement layer (layer 2) updates
  59. // the altref frame.
  60. static int GetFrameFlags(int frame_num, int num_temp_layers) {
  61. int frame_flags = 0;
  62. if (num_temp_layers == 2) {
  63. if (frame_num % 2 == 0) {
  64. // Layer 0: predict from L and ARF, update L.
  65. frame_flags =
  66. VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
  67. } else {
  68. // Layer 1: predict from L, G and ARF, and update G.
  69. frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
  70. VP8_EFLAG_NO_UPD_ENTROPY;
  71. }
  72. } else if (num_temp_layers == 3) {
  73. if (frame_num % 4 == 0) {
  74. // Layer 0: predict from L and ARF; update L.
  75. frame_flags =
  76. VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
  77. } else if ((frame_num - 2) % 4 == 0) {
  78. // Layer 1: predict from L, G, ARF; update G.
  79. frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
  80. } else if ((frame_num - 1) % 2 == 0) {
  81. // Layer 2: predict from L, G, ARF; update ARF.
  82. frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
  83. }
  84. }
  85. return frame_flags;
  86. }
  87. static int SetLayerId(int frame_num, int num_temp_layers) {
  88. int layer_id = 0;
  89. if (num_temp_layers == 2) {
  90. if (frame_num % 2 == 0) {
  91. layer_id = 0;
  92. } else {
  93. layer_id = 1;
  94. }
  95. } else if (num_temp_layers == 3) {
  96. if (frame_num % 4 == 0) {
  97. layer_id = 0;
  98. } else if ((frame_num - 2) % 4 == 0) {
  99. layer_id = 1;
  100. } else if ((frame_num - 1) % 2 == 0) {
  101. layer_id = 2;
  102. }
  103. }
  104. return layer_id;
  105. }
  106. virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
  107. ::libvpx_test::Encoder *encoder) {
  108. if (video->frame() == 0) {
  109. encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
  110. encoder->Control(VP9E_SET_AQ_MODE, aq_mode_);
  111. encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_);
  112. }
  113. if (denoiser_offon_test_) {
  114. ASSERT_GT(denoiser_offon_period_, 0)
  115. << "denoiser_offon_period_ is not positive.";
  116. if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
  117. // Flip denoiser_on_ periodically
  118. denoiser_on_ ^= 1;
  119. }
  120. }
  121. encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
  122. encoder->Control(VP9E_SET_TILE_COLUMNS, get_msb(cfg_.g_threads));
  123. encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING,
  124. frame_parallel_decoding_mode_);
  125. if (use_roi_) {
  126. encoder->Control(VP9E_SET_ROI_MAP, &roi_);
  127. encoder->Control(VP9E_SET_AQ_MODE, 0);
  128. }
  129. if (cfg_.ts_number_layers > 1) {
  130. if (video->frame() == 0) {
  131. encoder->Control(VP9E_SET_SVC, 1);
  132. }
  133. vpx_svc_layer_id_t layer_id;
  134. layer_id.spatial_layer_id = 0;
  135. frame_flags_ = GetFrameFlags(video->frame(), cfg_.ts_number_layers);
  136. layer_id.temporal_layer_id =
  137. SetLayerId(video->frame(), cfg_.ts_number_layers);
  138. layer_id.temporal_layer_id_per_spatial[0] =
  139. SetLayerId(video->frame(), cfg_.ts_number_layers);
  140. encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
  141. }
  142. const vpx_rational_t tb = video->timebase();
  143. timebase_ = static_cast<double>(tb.num) / tb.den;
  144. duration_ = 0;
  145. }
  146. virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
  147. // Time since last timestamp = duration.
  148. vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
  149. if (duration > 1) {
  150. // If first drop not set and we have a drop set it to this time.
  151. if (!first_drop_) first_drop_ = last_pts_ + 1;
  152. // Update the number of frame drops.
  153. num_drops_ += static_cast<int>(duration - 1);
  154. // Update counter for total number of frames (#frames input to encoder).
  155. // Needed for setting the proper layer_id below.
  156. tot_frame_number_ += static_cast<int>(duration - 1);
  157. }
  158. int layer = SetLayerId(tot_frame_number_, cfg_.ts_number_layers);
  159. // Add to the buffer the bits we'd expect from a constant bitrate server.
  160. bits_in_buffer_model_ += static_cast<int64_t>(
  161. duration * timebase_ * cfg_.rc_target_bitrate * 1000);
  162. // Buffer should not go negative.
  163. ASSERT_GE(bits_in_buffer_model_, 0)
  164. << "Buffer Underrun at frame " << pkt->data.frame.pts;
  165. const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
  166. // Update the total encoded bits. For temporal layers, update the cumulative
  167. // encoded bits per layer.
  168. for (int i = layer; i < static_cast<int>(cfg_.ts_number_layers); ++i) {
  169. bits_total_[i] += frame_size_in_bits;
  170. }
  171. // Update the most recent pts.
  172. last_pts_ = pkt->data.frame.pts;
  173. ++frame_number_;
  174. ++tot_frame_number_;
  175. }
  176. virtual void EndPassHook(void) {
  177. for (int layer = 0; layer < static_cast<int>(cfg_.ts_number_layers);
  178. ++layer) {
  179. duration_ = (last_pts_ + 1) * timebase_;
  180. if (bits_total_[layer]) {
  181. // Effective file datarate:
  182. effective_datarate_[layer] = (bits_total_[layer] / 1000.0) / duration_;
  183. }
  184. }
  185. }
  186. vpx_codec_pts_t last_pts_;
  187. double timebase_;
  188. int tune_content_;
  189. int frame_number_; // Counter for number of non-dropped/encoded frames.
  190. int tot_frame_number_; // Counter for total number of input frames.
  191. int64_t bits_total_[3];
  192. double duration_;
  193. double effective_datarate_[3];
  194. int set_cpu_used_;
  195. int64_t bits_in_buffer_model_;
  196. vpx_codec_pts_t first_drop_;
  197. int num_drops_;
  198. int aq_mode_;
  199. int denoiser_on_;
  200. int denoiser_offon_test_;
  201. int denoiser_offon_period_;
  202. int frame_parallel_decoding_mode_;
  203. bool use_roi_;
  204. vpx_roi_map_t roi_;
  205. };
  206. // Params: test mode, speed setting and index for bitrate array.
  207. class DatarateTestVP9RealTimeMultiBR
  208. : public DatarateTestVP9,
  209. public ::libvpx_test::CodecTestWith2Params<int, int> {
  210. public:
  211. DatarateTestVP9RealTimeMultiBR() : DatarateTestVP9(GET_PARAM(0)) {}
  212. protected:
  213. virtual void SetUp() {
  214. InitializeConfig();
  215. SetMode(::libvpx_test::kRealTime);
  216. set_cpu_used_ = GET_PARAM(1);
  217. ResetModel();
  218. }
  219. };
  220. // Params: speed setting and index for bitrate array.
  221. class DatarateTestVP9LargeVBR
  222. : public DatarateTestVP9,
  223. public ::libvpx_test::CodecTestWith2Params<int, int> {
  224. public:
  225. DatarateTestVP9LargeVBR() : DatarateTestVP9(GET_PARAM(0)) {}
  226. protected:
  227. virtual void SetUp() {
  228. InitializeConfig();
  229. SetMode(::libvpx_test::kRealTime);
  230. set_cpu_used_ = GET_PARAM(1);
  231. ResetModel();
  232. }
  233. };
  234. // Check basic rate targeting for VBR mode with 0 lag.
  235. TEST_P(DatarateTestVP9LargeVBR, BasicRateTargetingVBRLagZero) {
  236. cfg_.rc_min_quantizer = 0;
  237. cfg_.rc_max_quantizer = 63;
  238. cfg_.g_error_resilient = 0;
  239. cfg_.rc_end_usage = VPX_VBR;
  240. cfg_.g_lag_in_frames = 0;
  241. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  242. 30, 1, 0, 300);
  243. const int bitrates[2] = { 400, 800 };
  244. const int bitrate_index = GET_PARAM(2);
  245. cfg_.rc_target_bitrate = bitrates[bitrate_index];
  246. ResetModel();
  247. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  248. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
  249. << " The datarate for the file is lower than target by too much!";
  250. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.36)
  251. << " The datarate for the file is greater than target by too much!";
  252. }
  253. // Check basic rate targeting for VBR mode with non-zero lag.
  254. TEST_P(DatarateTestVP9LargeVBR, BasicRateTargetingVBRLagNonZero) {
  255. cfg_.rc_min_quantizer = 0;
  256. cfg_.rc_max_quantizer = 63;
  257. cfg_.g_error_resilient = 0;
  258. cfg_.rc_end_usage = VPX_VBR;
  259. // For non-zero lag, rate control will work (be within bounds) for
  260. // real-time mode.
  261. if (deadline_ == VPX_DL_REALTIME) {
  262. cfg_.g_lag_in_frames = 15;
  263. } else {
  264. cfg_.g_lag_in_frames = 0;
  265. }
  266. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  267. 30, 1, 0, 300);
  268. const int bitrates[2] = { 400, 800 };
  269. const int bitrate_index = GET_PARAM(2);
  270. cfg_.rc_target_bitrate = bitrates[bitrate_index];
  271. ResetModel();
  272. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  273. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
  274. << " The datarate for the file is lower than target by too much!";
  275. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.35)
  276. << " The datarate for the file is greater than target by too much!";
  277. }
  278. // Check basic rate targeting for VBR mode with non-zero lag, with
  279. // frame_parallel_decoding_mode off. This enables the adapt_coeff/mode/mv probs
  280. // since error_resilience is off.
  281. TEST_P(DatarateTestVP9LargeVBR, BasicRateTargetingVBRLagNonZeroFrameParDecOff) {
  282. cfg_.rc_min_quantizer = 0;
  283. cfg_.rc_max_quantizer = 63;
  284. cfg_.g_error_resilient = 0;
  285. cfg_.rc_end_usage = VPX_VBR;
  286. // For non-zero lag, rate control will work (be within bounds) for
  287. // real-time mode.
  288. if (deadline_ == VPX_DL_REALTIME) {
  289. cfg_.g_lag_in_frames = 15;
  290. } else {
  291. cfg_.g_lag_in_frames = 0;
  292. }
  293. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  294. 30, 1, 0, 300);
  295. const int bitrates[2] = { 400, 800 };
  296. const int bitrate_index = GET_PARAM(2);
  297. cfg_.rc_target_bitrate = bitrates[bitrate_index];
  298. ResetModel();
  299. frame_parallel_decoding_mode_ = 0;
  300. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  301. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
  302. << " The datarate for the file is lower than target by too much!";
  303. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.35)
  304. << " The datarate for the file is greater than target by too much!";
  305. }
  306. // Check basic rate targeting for CBR mode.
  307. TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting) {
  308. cfg_.rc_buf_initial_sz = 500;
  309. cfg_.rc_buf_optimal_sz = 500;
  310. cfg_.rc_buf_sz = 1000;
  311. cfg_.rc_dropframe_thresh = 1;
  312. cfg_.rc_min_quantizer = 0;
  313. cfg_.rc_max_quantizer = 63;
  314. cfg_.rc_end_usage = VPX_CBR;
  315. cfg_.g_lag_in_frames = 0;
  316. ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
  317. 0, 400);
  318. const int bitrates[4] = { 150, 350, 550, 750 };
  319. const int bitrate_index = GET_PARAM(2);
  320. cfg_.rc_target_bitrate = bitrates[bitrate_index];
  321. ResetModel();
  322. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  323. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  324. << " The datarate for the file is lower than target by too much!";
  325. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
  326. << " The datarate for the file is greater than target by too much!";
  327. }
  328. // Check basic rate targeting for CBR mode, with frame_parallel_decoding_mode
  329. // off( and error_resilience off).
  330. TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargetingFrameParDecOff) {
  331. cfg_.rc_buf_initial_sz = 500;
  332. cfg_.rc_buf_optimal_sz = 500;
  333. cfg_.rc_buf_sz = 1000;
  334. cfg_.rc_dropframe_thresh = 1;
  335. cfg_.rc_min_quantizer = 0;
  336. cfg_.rc_max_quantizer = 63;
  337. cfg_.rc_end_usage = VPX_CBR;
  338. cfg_.g_lag_in_frames = 0;
  339. cfg_.g_error_resilient = 0;
  340. ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
  341. 0, 400);
  342. const int bitrates[4] = { 150, 350, 550, 750 };
  343. const int bitrate_index = GET_PARAM(2);
  344. cfg_.rc_target_bitrate = bitrates[bitrate_index];
  345. ResetModel();
  346. frame_parallel_decoding_mode_ = 0;
  347. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  348. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  349. << " The datarate for the file is lower than target by too much!";
  350. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
  351. << " The datarate for the file is greater than target by too much!";
  352. }
  353. // Check basic rate targeting for CBR.
  354. TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting444) {
  355. ::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
  356. cfg_.g_profile = 1;
  357. cfg_.g_timebase = video.timebase();
  358. cfg_.rc_buf_initial_sz = 500;
  359. cfg_.rc_buf_optimal_sz = 500;
  360. cfg_.rc_buf_sz = 1000;
  361. cfg_.rc_dropframe_thresh = 1;
  362. cfg_.rc_min_quantizer = 0;
  363. cfg_.rc_max_quantizer = 63;
  364. cfg_.rc_end_usage = VPX_CBR;
  365. const int bitrates[4] = { 250, 450, 650, 850 };
  366. const int bitrate_index = GET_PARAM(2);
  367. cfg_.rc_target_bitrate = bitrates[bitrate_index];
  368. ResetModel();
  369. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  370. ASSERT_GE(static_cast<double>(cfg_.rc_target_bitrate),
  371. effective_datarate_[0] * 0.80)
  372. << " The datarate for the file exceeds the target by too much!";
  373. ASSERT_LE(static_cast<double>(cfg_.rc_target_bitrate),
  374. effective_datarate_[0] * 1.15)
  375. << " The datarate for the file missed the target!"
  376. << cfg_.rc_target_bitrate << " " << effective_datarate_;
  377. }
  378. // Check that (1) the first dropped frame gets earlier and earlier
  379. // as the drop frame threshold is increased, and (2) that the total number of
  380. // frame drops does not decrease as we increase frame drop threshold.
  381. // Use a lower qp-max to force some frame drops.
  382. TEST_P(DatarateTestVP9RealTimeMultiBR, ChangingDropFrameThresh) {
  383. cfg_.rc_buf_initial_sz = 500;
  384. cfg_.rc_buf_optimal_sz = 500;
  385. cfg_.rc_buf_sz = 1000;
  386. cfg_.rc_undershoot_pct = 20;
  387. cfg_.rc_undershoot_pct = 20;
  388. cfg_.rc_dropframe_thresh = 10;
  389. cfg_.rc_min_quantizer = 0;
  390. cfg_.rc_max_quantizer = 50;
  391. cfg_.rc_end_usage = VPX_CBR;
  392. cfg_.rc_target_bitrate = 200;
  393. cfg_.g_lag_in_frames = 0;
  394. // TODO(marpan): Investigate datarate target failures with a smaller keyframe
  395. // interval (128).
  396. cfg_.kf_max_dist = 9999;
  397. ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
  398. 0, 400);
  399. const int kDropFrameThreshTestStep = 30;
  400. const int bitrates[2] = { 50, 150 };
  401. const int bitrate_index = GET_PARAM(2);
  402. if (bitrate_index > 1) return;
  403. cfg_.rc_target_bitrate = bitrates[bitrate_index];
  404. vpx_codec_pts_t last_drop = 140;
  405. int last_num_drops = 0;
  406. for (int i = 10; i < 100; i += kDropFrameThreshTestStep) {
  407. cfg_.rc_dropframe_thresh = i;
  408. ResetModel();
  409. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  410. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  411. << " The datarate for the file is lower than target by too much!";
  412. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
  413. << " The datarate for the file is greater than target by too much!";
  414. ASSERT_LE(first_drop_, last_drop)
  415. << " The first dropped frame for drop_thresh " << i
  416. << " > first dropped frame for drop_thresh "
  417. << i - kDropFrameThreshTestStep;
  418. ASSERT_GE(num_drops_, last_num_drops * 0.85)
  419. << " The number of dropped frames for drop_thresh " << i
  420. << " < number of dropped frames for drop_thresh "
  421. << i - kDropFrameThreshTestStep;
  422. last_drop = first_drop_;
  423. last_num_drops = num_drops_;
  424. }
  425. } // namespace
  426. // Check basic rate targeting for 2 temporal layers.
  427. TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting2TemporalLayers) {
  428. cfg_.rc_buf_initial_sz = 500;
  429. cfg_.rc_buf_optimal_sz = 500;
  430. cfg_.rc_buf_sz = 1000;
  431. cfg_.rc_dropframe_thresh = 1;
  432. cfg_.rc_min_quantizer = 0;
  433. cfg_.rc_max_quantizer = 63;
  434. cfg_.rc_end_usage = VPX_CBR;
  435. cfg_.g_lag_in_frames = 0;
  436. // 2 Temporal layers, no spatial layers: Framerate decimation (2, 1).
  437. cfg_.ss_number_layers = 1;
  438. cfg_.ts_number_layers = 2;
  439. cfg_.ts_rate_decimator[0] = 2;
  440. cfg_.ts_rate_decimator[1] = 1;
  441. cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
  442. ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
  443. 0, 400);
  444. const int bitrates[4] = { 200, 400, 600, 800 };
  445. const int bitrate_index = GET_PARAM(2);
  446. cfg_.rc_target_bitrate = bitrates[bitrate_index];
  447. ResetModel();
  448. // 60-40 bitrate allocation for 2 temporal layers.
  449. cfg_.layer_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
  450. cfg_.layer_target_bitrate[1] = cfg_.rc_target_bitrate;
  451. aq_mode_ = 0;
  452. if (deadline_ == VPX_DL_REALTIME) {
  453. aq_mode_ = 3;
  454. cfg_.g_error_resilient = 1;
  455. }
  456. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  457. for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
  458. ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
  459. << " The datarate for the file is lower than target by too much, "
  460. "for layer: "
  461. << j;
  462. ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
  463. << " The datarate for the file is greater than target by too much, "
  464. "for layer: "
  465. << j;
  466. }
  467. }
  468. // Check basic rate targeting for 3 temporal layers.
  469. TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting3TemporalLayers) {
  470. cfg_.rc_buf_initial_sz = 500;
  471. cfg_.rc_buf_optimal_sz = 500;
  472. cfg_.rc_buf_sz = 1000;
  473. cfg_.rc_dropframe_thresh = 1;
  474. cfg_.rc_min_quantizer = 0;
  475. cfg_.rc_max_quantizer = 63;
  476. cfg_.rc_end_usage = VPX_CBR;
  477. cfg_.g_lag_in_frames = 0;
  478. // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
  479. cfg_.ss_number_layers = 1;
  480. cfg_.ts_number_layers = 3;
  481. cfg_.ts_rate_decimator[0] = 4;
  482. cfg_.ts_rate_decimator[1] = 2;
  483. cfg_.ts_rate_decimator[2] = 1;
  484. cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
  485. ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
  486. 0, 400);
  487. const int bitrates[4] = { 200, 400, 600, 800 };
  488. const int bitrate_index = GET_PARAM(2);
  489. cfg_.rc_target_bitrate = bitrates[bitrate_index];
  490. ResetModel();
  491. // 40-20-40 bitrate allocation for 3 temporal layers.
  492. cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
  493. cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
  494. cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
  495. aq_mode_ = 0;
  496. if (deadline_ == VPX_DL_REALTIME) {
  497. aq_mode_ = 3;
  498. cfg_.g_error_resilient = 1;
  499. }
  500. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  501. for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
  502. // TODO(yaowu): Work out more stable rc control strategy and
  503. // Adjust the thresholds to be tighter than .75.
  504. ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.75)
  505. << " The datarate for the file is lower than target by too much, "
  506. "for layer: "
  507. << j;
  508. // TODO(yaowu): Work out more stable rc control strategy and
  509. // Adjust the thresholds to be tighter than 1.25.
  510. ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.25)
  511. << " The datarate for the file is greater than target by too much, "
  512. "for layer: "
  513. << j;
  514. }
  515. }
  516. // Params: speed setting.
  517. class DatarateTestVP9RealTime : public DatarateTestVP9,
  518. public ::libvpx_test::CodecTestWithParam<int> {
  519. public:
  520. DatarateTestVP9RealTime() : DatarateTestVP9(GET_PARAM(0)) {}
  521. virtual ~DatarateTestVP9RealTime() {}
  522. protected:
  523. virtual void SetUp() {
  524. InitializeConfig();
  525. SetMode(::libvpx_test::kRealTime);
  526. set_cpu_used_ = GET_PARAM(1);
  527. ResetModel();
  528. }
  529. };
  530. // Check basic rate targeting for CBR mode, with 2 threads and dropped frames.
  531. TEST_P(DatarateTestVP9RealTime, BasicRateTargetingDropFramesMultiThreads) {
  532. cfg_.rc_buf_initial_sz = 500;
  533. cfg_.rc_buf_optimal_sz = 500;
  534. cfg_.rc_buf_sz = 1000;
  535. cfg_.rc_dropframe_thresh = 30;
  536. cfg_.rc_min_quantizer = 0;
  537. cfg_.rc_max_quantizer = 63;
  538. cfg_.rc_end_usage = VPX_CBR;
  539. cfg_.g_lag_in_frames = 0;
  540. // Encode using multiple threads.
  541. cfg_.g_threads = 2;
  542. ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
  543. 0, 400);
  544. cfg_.rc_target_bitrate = 200;
  545. ResetModel();
  546. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  547. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  548. << " The datarate for the file is lower than target by too much!";
  549. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
  550. << " The datarate for the file is greater than target by too much!";
  551. }
  552. // Check basic rate targeting for 3 temporal layers, with frame dropping.
  553. // Only for one (low) bitrate with lower max_quantizer, and somewhat higher
  554. // frame drop threshold, to force frame dropping.
  555. TEST_P(DatarateTestVP9RealTime,
  556. BasicRateTargeting3TemporalLayersFrameDropping) {
  557. cfg_.rc_buf_initial_sz = 500;
  558. cfg_.rc_buf_optimal_sz = 500;
  559. cfg_.rc_buf_sz = 1000;
  560. // Set frame drop threshold and rc_max_quantizer to force some frame drops.
  561. cfg_.rc_dropframe_thresh = 20;
  562. cfg_.rc_max_quantizer = 45;
  563. cfg_.rc_min_quantizer = 0;
  564. cfg_.rc_end_usage = VPX_CBR;
  565. cfg_.g_lag_in_frames = 0;
  566. // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
  567. cfg_.ss_number_layers = 1;
  568. cfg_.ts_number_layers = 3;
  569. cfg_.ts_rate_decimator[0] = 4;
  570. cfg_.ts_rate_decimator[1] = 2;
  571. cfg_.ts_rate_decimator[2] = 1;
  572. cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
  573. ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
  574. 0, 400);
  575. cfg_.rc_target_bitrate = 200;
  576. ResetModel();
  577. // 40-20-40 bitrate allocation for 3 temporal layers.
  578. cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
  579. cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
  580. cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
  581. aq_mode_ = 0;
  582. if (deadline_ == VPX_DL_REALTIME) {
  583. aq_mode_ = 3;
  584. cfg_.g_error_resilient = 1;
  585. }
  586. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  587. for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
  588. ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
  589. << " The datarate for the file is lower than target by too much, "
  590. "for layer: "
  591. << j;
  592. ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.20)
  593. << " The datarate for the file is greater than target by too much, "
  594. "for layer: "
  595. << j;
  596. // Expect some frame drops in this test: for this 200 frames test,
  597. // expect at least 10% and not more than 60% drops.
  598. ASSERT_GE(num_drops_, 20);
  599. ASSERT_LE(num_drops_, 280);
  600. }
  601. }
  602. // Check VP9 region of interest feature.
  603. TEST_P(DatarateTestVP9RealTime, RegionOfInterest) {
  604. if (deadline_ != VPX_DL_REALTIME || set_cpu_used_ < 5) return;
  605. cfg_.rc_buf_initial_sz = 500;
  606. cfg_.rc_buf_optimal_sz = 500;
  607. cfg_.rc_buf_sz = 1000;
  608. cfg_.rc_dropframe_thresh = 0;
  609. cfg_.rc_min_quantizer = 0;
  610. cfg_.rc_max_quantizer = 63;
  611. cfg_.rc_end_usage = VPX_CBR;
  612. cfg_.g_lag_in_frames = 0;
  613. ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
  614. 0, 400);
  615. cfg_.rc_target_bitrate = 450;
  616. cfg_.g_w = 640;
  617. cfg_.g_h = 480;
  618. ResetModel();
  619. // Set ROI parameters
  620. use_roi_ = true;
  621. memset(&roi_, 0, sizeof(roi_));
  622. roi_.rows = (cfg_.g_h + 7) / 8;
  623. roi_.cols = (cfg_.g_w + 7) / 8;
  624. roi_.delta_q[1] = -20;
  625. roi_.delta_lf[1] = -20;
  626. memset(roi_.ref_frame, -1, sizeof(roi_.ref_frame));
  627. roi_.ref_frame[1] = 1;
  628. // Use 2 states: 1 is center square, 0 is the rest.
  629. roi_.roi_map = reinterpret_cast<uint8_t *>(
  630. calloc(roi_.rows * roi_.cols, sizeof(*roi_.roi_map)));
  631. ASSERT_TRUE(roi_.roi_map != NULL);
  632. for (unsigned int i = 0; i < roi_.rows; ++i) {
  633. for (unsigned int j = 0; j < roi_.cols; ++j) {
  634. if (i > (roi_.rows >> 2) && i < ((roi_.rows * 3) >> 2) &&
  635. j > (roi_.cols >> 2) && j < ((roi_.cols * 3) >> 2)) {
  636. roi_.roi_map[i * roi_.cols + j] = 1;
  637. }
  638. }
  639. }
  640. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  641. ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_[0] * 0.90)
  642. << " The datarate for the file exceeds the target!";
  643. ASSERT_LE(cfg_.rc_target_bitrate, effective_datarate_[0] * 1.4)
  644. << " The datarate for the file missed the target!";
  645. free(roi_.roi_map);
  646. }
  647. // Params: test mode, speed setting and index for bitrate array.
  648. class DatarateTestVP9PostEncodeDrop
  649. : public DatarateTestVP9,
  650. public ::libvpx_test::CodecTestWithParam<int> {
  651. public:
  652. DatarateTestVP9PostEncodeDrop() : DatarateTestVP9(GET_PARAM(0)) {}
  653. protected:
  654. virtual void SetUp() {
  655. InitializeConfig();
  656. SetMode(::libvpx_test::kRealTime);
  657. set_cpu_used_ = GET_PARAM(1);
  658. ResetModel();
  659. }
  660. };
  661. // Check basic rate targeting for CBR mode, with 2 threads and dropped frames.
  662. TEST_P(DatarateTestVP9PostEncodeDrop, PostEncodeDropScreenContent) {
  663. cfg_.rc_buf_initial_sz = 500;
  664. cfg_.rc_buf_optimal_sz = 500;
  665. cfg_.rc_buf_sz = 1000;
  666. cfg_.rc_dropframe_thresh = 30;
  667. cfg_.rc_min_quantizer = 0;
  668. cfg_.rc_max_quantizer = 56;
  669. cfg_.rc_end_usage = VPX_CBR;
  670. cfg_.g_lag_in_frames = 0;
  671. // Encode using multiple threads.
  672. cfg_.g_threads = 2;
  673. cfg_.g_error_resilient = 0;
  674. tune_content_ = 1;
  675. ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
  676. 30, 1, 0, 300);
  677. cfg_.rc_target_bitrate = 300;
  678. ResetModel();
  679. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  680. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  681. << " The datarate for the file is lower than target by too much!";
  682. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
  683. << " The datarate for the file is greater than target by too much!";
  684. }
  685. #if CONFIG_VP9_TEMPORAL_DENOISING
  686. // Params: speed setting.
  687. class DatarateTestVP9RealTimeDenoiser : public DatarateTestVP9RealTime {
  688. public:
  689. virtual ~DatarateTestVP9RealTimeDenoiser() {}
  690. };
  691. // Check basic datarate targeting, for a single bitrate, when denoiser is on.
  692. TEST_P(DatarateTestVP9RealTimeDenoiser, LowNoise) {
  693. cfg_.rc_buf_initial_sz = 500;
  694. cfg_.rc_buf_optimal_sz = 500;
  695. cfg_.rc_buf_sz = 1000;
  696. cfg_.rc_dropframe_thresh = 1;
  697. cfg_.rc_min_quantizer = 2;
  698. cfg_.rc_max_quantizer = 56;
  699. cfg_.rc_end_usage = VPX_CBR;
  700. cfg_.g_lag_in_frames = 0;
  701. ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
  702. 0, 400);
  703. // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
  704. // there is only one denoiser mode: denoiserYonly(which is 1),
  705. // but may add more modes in the future.
  706. cfg_.rc_target_bitrate = 400;
  707. ResetModel();
  708. // Turn on the denoiser.
  709. denoiser_on_ = 1;
  710. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  711. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  712. << " The datarate for the file is lower than target by too much!";
  713. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
  714. << " The datarate for the file is greater than target by too much!";
  715. }
  716. // Check basic datarate targeting, for a single bitrate, when denoiser is on,
  717. // for clip with high noise level. Use 2 threads.
  718. TEST_P(DatarateTestVP9RealTimeDenoiser, HighNoise) {
  719. cfg_.rc_buf_initial_sz = 500;
  720. cfg_.rc_buf_optimal_sz = 500;
  721. cfg_.rc_buf_sz = 1000;
  722. cfg_.rc_dropframe_thresh = 1;
  723. cfg_.rc_min_quantizer = 2;
  724. cfg_.rc_max_quantizer = 56;
  725. cfg_.rc_end_usage = VPX_CBR;
  726. cfg_.g_lag_in_frames = 0;
  727. cfg_.g_threads = 2;
  728. ::libvpx_test::Y4mVideoSource video("noisy_clip_640_360.y4m", 0, 200);
  729. // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
  730. // there is only one denoiser mode: kDenoiserOnYOnly(which is 1),
  731. // but may add more modes in the future.
  732. cfg_.rc_target_bitrate = 1000;
  733. ResetModel();
  734. // Turn on the denoiser.
  735. denoiser_on_ = 1;
  736. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  737. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  738. << " The datarate for the file is lower than target by too much!";
  739. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
  740. << " The datarate for the file is greater than target by too much!";
  741. }
  742. // Check basic datarate targeting, for a single bitrate, when denoiser is on,
  743. // for 1280x720 clip with 4 threads.
  744. TEST_P(DatarateTestVP9RealTimeDenoiser, 4threads) {
  745. cfg_.rc_buf_initial_sz = 500;
  746. cfg_.rc_buf_optimal_sz = 500;
  747. cfg_.rc_buf_sz = 1000;
  748. cfg_.rc_dropframe_thresh = 1;
  749. cfg_.rc_min_quantizer = 2;
  750. cfg_.rc_max_quantizer = 56;
  751. cfg_.rc_end_usage = VPX_CBR;
  752. cfg_.g_lag_in_frames = 0;
  753. cfg_.g_threads = 4;
  754. ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
  755. // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
  756. // there is only one denoiser mode: denoiserYonly(which is 1),
  757. // but may add more modes in the future.
  758. cfg_.rc_target_bitrate = 1000;
  759. ResetModel();
  760. // Turn on the denoiser.
  761. denoiser_on_ = 1;
  762. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  763. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  764. << " The datarate for the file is lower than target by too much!";
  765. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.29)
  766. << " The datarate for the file is greater than target by too much!";
  767. }
  768. // Check basic datarate targeting, for a single bitrate, when denoiser is off
  769. // and on.
  770. TEST_P(DatarateTestVP9RealTimeDenoiser, DenoiserOffOn) {
  771. cfg_.rc_buf_initial_sz = 500;
  772. cfg_.rc_buf_optimal_sz = 500;
  773. cfg_.rc_buf_sz = 1000;
  774. cfg_.rc_dropframe_thresh = 1;
  775. cfg_.rc_min_quantizer = 2;
  776. cfg_.rc_max_quantizer = 56;
  777. cfg_.rc_end_usage = VPX_CBR;
  778. cfg_.g_lag_in_frames = 0;
  779. ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
  780. 0, 400);
  781. // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
  782. // there is only one denoiser mode: denoiserYonly(which is 1),
  783. // but may add more modes in the future.
  784. cfg_.rc_target_bitrate = 400;
  785. ResetModel();
  786. // The denoiser is off by default.
  787. denoiser_on_ = 0;
  788. // Set the offon test flag.
  789. denoiser_offon_test_ = 1;
  790. denoiser_offon_period_ = 100;
  791. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  792. ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
  793. << " The datarate for the file is lower than target by too much!";
  794. ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
  795. << " The datarate for the file is greater than target by too much!";
  796. }
  797. #endif // CONFIG_VP9_TEMPORAL_DENOISING
  798. VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9RealTimeMultiBR,
  799. ::testing::Range(5, 10), ::testing::Range(0, 4));
  800. VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9LargeVBR, ::testing::Range(5, 9),
  801. ::testing::Range(0, 2));
  802. VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9RealTime, ::testing::Range(5, 10));
  803. VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9PostEncodeDrop,
  804. ::testing::Range(5, 6));
  805. #if CONFIG_VP9_TEMPORAL_DENOISING
  806. VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9RealTimeDenoiser,
  807. ::testing::Range(5, 10));
  808. #endif
  809. } // namespace