svc_end_to_end_test.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. /*
  2. * Copyright (c) 2018 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/svc_test.h"
  16. #include "test/util.h"
  17. #include "test/y4m_video_source.h"
  18. #include "vpx/vpx_codec.h"
  19. #include "vpx_ports/bitops.h"
  20. namespace svc_test {
  21. namespace {
  22. typedef enum {
  23. // Inter-layer prediction is on on all frames.
  24. INTER_LAYER_PRED_ON,
  25. // Inter-layer prediction is off on all frames.
  26. INTER_LAYER_PRED_OFF,
  27. // Inter-layer prediction is off on non-key frames and non-sync frames.
  28. INTER_LAYER_PRED_OFF_NONKEY,
  29. // Inter-layer prediction is on on all frames, but constrained such
  30. // that any layer S (> 0) can only predict from previous spatial
  31. // layer S-1, from the same superframe.
  32. INTER_LAYER_PRED_ON_CONSTRAINED
  33. } INTER_LAYER_PRED;
  34. class ScalePartitionOnePassCbrSvc
  35. : public OnePassCbrSvc,
  36. public ::testing::TestWithParam<const ::libvpx_test::CodecFactory *> {
  37. public:
  38. ScalePartitionOnePassCbrSvc()
  39. : OnePassCbrSvc(GetParam()), mismatch_nframes_(0), num_nonref_frames_(0) {
  40. SetMode(::libvpx_test::kRealTime);
  41. }
  42. protected:
  43. virtual ~ScalePartitionOnePassCbrSvc() {}
  44. virtual void SetUp() {
  45. InitializeConfig();
  46. speed_setting_ = 7;
  47. }
  48. virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
  49. ::libvpx_test::Encoder *encoder) {
  50. PreEncodeFrameHookSetup(video, encoder);
  51. }
  52. virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
  53. // Keep track of number of non-reference frames, needed for mismatch check.
  54. // Non-reference frames are top spatial and temporal layer frames,
  55. // for TL > 0.
  56. if (temporal_layer_id_ == number_temporal_layers_ - 1 &&
  57. temporal_layer_id_ > 0 &&
  58. pkt->data.frame.spatial_layer_encoded[number_spatial_layers_ - 1])
  59. num_nonref_frames_++;
  60. }
  61. virtual void MismatchHook(const vpx_image_t * /*img1*/,
  62. const vpx_image_t * /*img2*/) {
  63. ++mismatch_nframes_;
  64. }
  65. virtual void SetConfig(const int /*num_temporal_layer*/) {}
  66. unsigned int GetMismatchFrames() const { return mismatch_nframes_; }
  67. unsigned int GetNonRefFrames() const { return num_nonref_frames_; }
  68. private:
  69. unsigned int mismatch_nframes_;
  70. unsigned int num_nonref_frames_;
  71. };
  72. TEST_P(ScalePartitionOnePassCbrSvc, OnePassCbrSvc3SL3TL1080P) {
  73. SetSvcConfig(3, 3);
  74. cfg_.rc_buf_initial_sz = 500;
  75. cfg_.rc_buf_optimal_sz = 500;
  76. cfg_.rc_buf_sz = 1000;
  77. cfg_.rc_min_quantizer = 0;
  78. cfg_.rc_max_quantizer = 63;
  79. cfg_.g_threads = 1;
  80. cfg_.rc_dropframe_thresh = 10;
  81. cfg_.rc_target_bitrate = 800;
  82. cfg_.kf_max_dist = 9999;
  83. cfg_.rc_end_usage = VPX_CBR;
  84. cfg_.g_lag_in_frames = 0;
  85. cfg_.g_error_resilient = 1;
  86. cfg_.ts_rate_decimator[0] = 4;
  87. cfg_.ts_rate_decimator[1] = 2;
  88. cfg_.ts_rate_decimator[2] = 1;
  89. cfg_.temporal_layering_mode = 3;
  90. ::libvpx_test::I420VideoSource video(
  91. "slides_code_term_web_plot.1920_1080.yuv", 1920, 1080, 30, 1, 0, 100);
  92. // For this 3 temporal layer case, pattern repeats every 4 frames, so choose
  93. // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
  94. AssignLayerBitrates();
  95. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  96. #if CONFIG_VP9_DECODER
  97. // The non-reference frames are expected to be mismatched frames as the
  98. // encoder will avoid loopfilter on these frames.
  99. EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
  100. #endif
  101. }
  102. // Params: Inter layer prediction modes.
  103. class SyncFrameOnePassCbrSvc : public OnePassCbrSvc,
  104. public ::libvpx_test::CodecTestWithParam<int> {
  105. public:
  106. SyncFrameOnePassCbrSvc()
  107. : OnePassCbrSvc(GET_PARAM(0)), current_video_frame_(0),
  108. frame_to_start_decode_(0), frame_to_sync_(0),
  109. inter_layer_pred_mode_(GET_PARAM(1)), decode_to_layer_before_sync_(-1),
  110. decode_to_layer_after_sync_(-1), denoiser_on_(0),
  111. intra_only_test_(false), mismatch_nframes_(0), num_nonref_frames_(0) {
  112. SetMode(::libvpx_test::kRealTime);
  113. memset(&svc_layer_sync_, 0, sizeof(svc_layer_sync_));
  114. }
  115. protected:
  116. virtual ~SyncFrameOnePassCbrSvc() {}
  117. virtual void SetUp() {
  118. InitializeConfig();
  119. speed_setting_ = 7;
  120. }
  121. virtual bool DoDecode() const {
  122. return current_video_frame_ >= frame_to_start_decode_;
  123. }
  124. virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
  125. ::libvpx_test::Encoder *encoder) {
  126. current_video_frame_ = video->frame();
  127. PreEncodeFrameHookSetup(video, encoder);
  128. if (video->frame() == 0) {
  129. // Do not turn off inter-layer pred completely because simulcast mode
  130. // fails.
  131. if (inter_layer_pred_mode_ != INTER_LAYER_PRED_OFF)
  132. encoder->Control(VP9E_SET_SVC_INTER_LAYER_PRED, inter_layer_pred_mode_);
  133. encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
  134. if (intra_only_test_)
  135. // Decoder sets the color_space for Intra-only frames
  136. // to BT_601 (see line 1810 in vp9_decodeframe.c).
  137. // So set it here in these tess to avoid encoder-decoder
  138. // mismatch check on color space setting.
  139. encoder->Control(VP9E_SET_COLOR_SPACE, VPX_CS_BT_601);
  140. }
  141. if (video->frame() == frame_to_sync_) {
  142. encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync_);
  143. }
  144. }
  145. #if CONFIG_VP9_DECODER
  146. virtual void PreDecodeFrameHook(::libvpx_test::VideoSource *video,
  147. ::libvpx_test::Decoder *decoder) {
  148. if (video->frame() < frame_to_sync_) {
  149. if (decode_to_layer_before_sync_ >= 0)
  150. decoder->Control(VP9_DECODE_SVC_SPATIAL_LAYER,
  151. decode_to_layer_before_sync_);
  152. } else {
  153. if (decode_to_layer_after_sync_ >= 0)
  154. decoder->Control(VP9_DECODE_SVC_SPATIAL_LAYER,
  155. decode_to_layer_after_sync_);
  156. }
  157. }
  158. #endif
  159. virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
  160. // Keep track of number of non-reference frames, needed for mismatch check.
  161. // Non-reference frames are top spatial and temporal layer frames,
  162. // for TL > 0.
  163. if (temporal_layer_id_ == number_temporal_layers_ - 1 &&
  164. temporal_layer_id_ > 0 &&
  165. pkt->data.frame.spatial_layer_encoded[number_spatial_layers_ - 1] &&
  166. current_video_frame_ >= frame_to_sync_)
  167. num_nonref_frames_++;
  168. if (intra_only_test_ && current_video_frame_ == frame_to_sync_) {
  169. // Intra-only frame is only generated for spatial layers > 1 and <= 3,
  170. // among other conditions (see constraint in set_intra_only_frame(). If
  171. // intra-only is no allowed then encoder will insert key frame instead.
  172. const bool key_frame =
  173. (pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
  174. if (number_spatial_layers_ == 1 || number_spatial_layers_ > 3)
  175. ASSERT_TRUE(key_frame);
  176. else
  177. ASSERT_FALSE(key_frame);
  178. }
  179. }
  180. virtual void MismatchHook(const vpx_image_t * /*img1*/,
  181. const vpx_image_t * /*img2*/) {
  182. if (current_video_frame_ >= frame_to_sync_) ++mismatch_nframes_;
  183. }
  184. unsigned int GetMismatchFrames() const { return mismatch_nframes_; }
  185. unsigned int GetNonRefFrames() const { return num_nonref_frames_; }
  186. unsigned int current_video_frame_;
  187. unsigned int frame_to_start_decode_;
  188. unsigned int frame_to_sync_;
  189. int inter_layer_pred_mode_;
  190. int decode_to_layer_before_sync_;
  191. int decode_to_layer_after_sync_;
  192. int denoiser_on_;
  193. bool intra_only_test_;
  194. vpx_svc_spatial_layer_sync_t svc_layer_sync_;
  195. private:
  196. virtual void SetConfig(const int num_temporal_layer) {
  197. cfg_.rc_buf_initial_sz = 500;
  198. cfg_.rc_buf_optimal_sz = 500;
  199. cfg_.rc_buf_sz = 1000;
  200. cfg_.rc_min_quantizer = 0;
  201. cfg_.rc_max_quantizer = 63;
  202. cfg_.rc_end_usage = VPX_CBR;
  203. cfg_.g_lag_in_frames = 0;
  204. cfg_.g_error_resilient = 1;
  205. cfg_.g_threads = 1;
  206. cfg_.rc_dropframe_thresh = 30;
  207. cfg_.kf_max_dist = 9999;
  208. if (num_temporal_layer == 3) {
  209. cfg_.ts_rate_decimator[0] = 4;
  210. cfg_.ts_rate_decimator[1] = 2;
  211. cfg_.ts_rate_decimator[2] = 1;
  212. cfg_.temporal_layering_mode = 3;
  213. } else if (num_temporal_layer == 2) {
  214. cfg_.ts_rate_decimator[0] = 2;
  215. cfg_.ts_rate_decimator[1] = 1;
  216. cfg_.temporal_layering_mode = 2;
  217. } else if (num_temporal_layer == 1) {
  218. cfg_.ts_rate_decimator[0] = 1;
  219. cfg_.temporal_layering_mode = 1;
  220. }
  221. }
  222. unsigned int mismatch_nframes_;
  223. unsigned int num_nonref_frames_;
  224. };
  225. // Test for sync layer for 1 pass CBR SVC: 3 spatial layers and
  226. // 3 temporal layers. Only start decoding on the sync layer.
  227. // Full sync: insert key frame on base layer.
  228. TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLFullSync) {
  229. SetSvcConfig(3, 3);
  230. // Sync is on base layer so the frame to sync and the frame to start decoding
  231. // is the same.
  232. frame_to_start_decode_ = 20;
  233. frame_to_sync_ = 20;
  234. decode_to_layer_before_sync_ = -1;
  235. decode_to_layer_after_sync_ = 2;
  236. // Set up svc layer sync structure.
  237. svc_layer_sync_.base_layer_intra_only = 0;
  238. svc_layer_sync_.spatial_layer_sync[0] = 1;
  239. ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
  240. cfg_.rc_target_bitrate = 600;
  241. AssignLayerBitrates();
  242. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  243. #if CONFIG_VP9_DECODER
  244. // The non-reference frames are expected to be mismatched frames as the
  245. // encoder will avoid loopfilter on these frames.
  246. EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
  247. #endif
  248. }
  249. // Test for sync layer for 1 pass CBR SVC: 2 spatial layers and
  250. // 3 temporal layers. Decoding QVGA before sync frame and decode up to
  251. // VGA on and after sync.
  252. TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc2SL3TLSyncToVGA) {
  253. SetSvcConfig(2, 3);
  254. frame_to_start_decode_ = 0;
  255. frame_to_sync_ = 100;
  256. decode_to_layer_before_sync_ = 0;
  257. decode_to_layer_after_sync_ = 1;
  258. // Set up svc layer sync structure.
  259. svc_layer_sync_.base_layer_intra_only = 0;
  260. svc_layer_sync_.spatial_layer_sync[0] = 0;
  261. svc_layer_sync_.spatial_layer_sync[1] = 1;
  262. ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
  263. 0, 400);
  264. cfg_.rc_target_bitrate = 400;
  265. AssignLayerBitrates();
  266. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  267. #if CONFIG_VP9_DECODER
  268. // The non-reference frames are expected to be mismatched frames as the
  269. // encoder will avoid loopfilter on these frames.
  270. EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
  271. #endif
  272. }
  273. // Test for sync layer for 1 pass CBR SVC: 3 spatial layers and
  274. // 3 temporal layers. Decoding QVGA and VGA before sync frame and decode up to
  275. // HD on and after sync.
  276. TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncToHD) {
  277. SetSvcConfig(3, 3);
  278. frame_to_start_decode_ = 0;
  279. frame_to_sync_ = 20;
  280. decode_to_layer_before_sync_ = 1;
  281. decode_to_layer_after_sync_ = 2;
  282. // Set up svc layer sync structure.
  283. svc_layer_sync_.base_layer_intra_only = 0;
  284. svc_layer_sync_.spatial_layer_sync[0] = 0;
  285. svc_layer_sync_.spatial_layer_sync[1] = 0;
  286. svc_layer_sync_.spatial_layer_sync[2] = 1;
  287. ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
  288. cfg_.rc_target_bitrate = 600;
  289. AssignLayerBitrates();
  290. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  291. #if CONFIG_VP9_DECODER
  292. // The non-reference frames are expected to be mismatched frames as the
  293. // encoder will avoid loopfilter on these frames.
  294. EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
  295. #endif
  296. }
  297. // Test for sync layer for 1 pass CBR SVC: 3 spatial layers and
  298. // 3 temporal layers. Decoding QVGA before sync frame and decode up to
  299. // HD on and after sync.
  300. TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncToVGAHD) {
  301. SetSvcConfig(3, 3);
  302. frame_to_start_decode_ = 0;
  303. frame_to_sync_ = 20;
  304. decode_to_layer_before_sync_ = 0;
  305. decode_to_layer_after_sync_ = 2;
  306. // Set up svc layer sync structure.
  307. svc_layer_sync_.base_layer_intra_only = 0;
  308. svc_layer_sync_.spatial_layer_sync[0] = 0;
  309. svc_layer_sync_.spatial_layer_sync[1] = 1;
  310. svc_layer_sync_.spatial_layer_sync[2] = 1;
  311. ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
  312. cfg_.rc_target_bitrate = 600;
  313. AssignLayerBitrates();
  314. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  315. #if CONFIG_VP9_DECODER
  316. // The non-reference frames are expected to be mismatched frames as the
  317. // encoder will avoid loopfilter on these frames.
  318. EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
  319. #endif
  320. }
  321. #if CONFIG_VP9_TEMPORAL_DENOISING
  322. // Test for sync layer for 1 pass CBR SVC: 2 spatial layers and
  323. // 3 temporal layers. Decoding QVGA before sync frame and decode up to
  324. // VGA on and after sync.
  325. TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc2SL3TLSyncFrameVGADenoise) {
  326. SetSvcConfig(2, 3);
  327. frame_to_start_decode_ = 0;
  328. frame_to_sync_ = 100;
  329. decode_to_layer_before_sync_ = 0;
  330. decode_to_layer_after_sync_ = 1;
  331. denoiser_on_ = 1;
  332. // Set up svc layer sync structure.
  333. svc_layer_sync_.base_layer_intra_only = 0;
  334. svc_layer_sync_.spatial_layer_sync[0] = 0;
  335. svc_layer_sync_.spatial_layer_sync[1] = 1;
  336. ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
  337. 0, 400);
  338. cfg_.rc_target_bitrate = 400;
  339. AssignLayerBitrates();
  340. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  341. #if CONFIG_VP9_DECODER
  342. // The non-reference frames are expected to be mismatched frames as the
  343. // encoder will avoid loopfilter on these frames.
  344. EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
  345. #endif
  346. }
  347. #endif
  348. // Start decoding from beginning of sequence, during sequence insert intra-only
  349. // on base/qvga layer. Decode all layers.
  350. TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncFrameIntraOnlyQVGA) {
  351. SetSvcConfig(3, 3);
  352. frame_to_start_decode_ = 0;
  353. frame_to_sync_ = 20;
  354. decode_to_layer_before_sync_ = 2;
  355. // The superframe containing intra-only layer will have 4 frames. Thus set the
  356. // layer to decode after sync frame to 3.
  357. decode_to_layer_after_sync_ = 3;
  358. intra_only_test_ = true;
  359. // Set up svc layer sync structure.
  360. svc_layer_sync_.base_layer_intra_only = 1;
  361. svc_layer_sync_.spatial_layer_sync[0] = 1;
  362. svc_layer_sync_.spatial_layer_sync[1] = 0;
  363. svc_layer_sync_.spatial_layer_sync[2] = 0;
  364. ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
  365. cfg_.rc_target_bitrate = 600;
  366. AssignLayerBitrates();
  367. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  368. #if CONFIG_VP9_DECODER
  369. // The non-reference frames are expected to be mismatched frames as the
  370. // encoder will avoid loopfilter on these frames.
  371. EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
  372. #endif
  373. }
  374. // Start decoding from beginning of sequence, during sequence insert intra-only
  375. // on base/qvga layer and sync_layer on middle/VGA layer. Decode all layers.
  376. TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncFrameIntraOnlyVGA) {
  377. SetSvcConfig(3, 3);
  378. frame_to_start_decode_ = 0;
  379. frame_to_sync_ = 20;
  380. decode_to_layer_before_sync_ = 2;
  381. // The superframe containing intra-only layer will have 4 frames. Thus set the
  382. // layer to decode after sync frame to 3.
  383. decode_to_layer_after_sync_ = 3;
  384. intra_only_test_ = true;
  385. // Set up svc layer sync structure.
  386. svc_layer_sync_.base_layer_intra_only = 1;
  387. svc_layer_sync_.spatial_layer_sync[0] = 1;
  388. svc_layer_sync_.spatial_layer_sync[1] = 1;
  389. svc_layer_sync_.spatial_layer_sync[2] = 0;
  390. ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
  391. cfg_.rc_target_bitrate = 600;
  392. AssignLayerBitrates();
  393. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  394. #if CONFIG_VP9_DECODER
  395. // The non-reference frames are expected to be mismatched frames as the
  396. // encoder will avoid loopfilter on these frames.
  397. EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
  398. #endif
  399. }
  400. // Start decoding from sync frame, insert intra-only on base/qvga layer. Decode
  401. // all layers. For 1 spatial layer, it inserts a key frame.
  402. TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc1SL3TLSyncFrameIntraOnlyQVGA) {
  403. SetSvcConfig(1, 3);
  404. frame_to_start_decode_ = 20;
  405. frame_to_sync_ = 20;
  406. decode_to_layer_before_sync_ = 0;
  407. decode_to_layer_after_sync_ = 0;
  408. intra_only_test_ = true;
  409. // Set up svc layer sync structure.
  410. svc_layer_sync_.base_layer_intra_only = 1;
  411. svc_layer_sync_.spatial_layer_sync[0] = 1;
  412. ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
  413. cfg_.rc_target_bitrate = 600;
  414. AssignLayerBitrates();
  415. ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  416. #if CONFIG_VP9_DECODER
  417. // The non-reference frames are expected to be mismatched frames as the
  418. // encoder will avoid loopfilter on these frames.
  419. EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
  420. #endif
  421. }
  422. VP9_INSTANTIATE_TEST_CASE(SyncFrameOnePassCbrSvc, ::testing::Range(0, 3));
  423. INSTANTIATE_TEST_CASE_P(
  424. VP9, ScalePartitionOnePassCbrSvc,
  425. ::testing::Values(
  426. static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)));
  427. } // namespace
  428. } // namespace svc_test