Extend LibvpxInterface with VP9 support and use it from LibvpxVp9Encoder

Bug: webrtc:12274
Change-Id: I7a66a91f6a21ba482347af3c8af53544f9eb2269
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/196900
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32822}
diff --git a/modules/video_coding/codecs/interface/libvpx_interface.cc b/modules/video_coding/codecs/interface/libvpx_interface.cc
index 8ab7bf5..b24922f 100644
--- a/modules/video_coding/codecs/interface/libvpx_interface.cc
+++ b/modules/video_coding/codecs/interface/libvpx_interface.cc
@@ -93,17 +93,45 @@
         return vpx_codec_control(ctx, VP8E_SET_ARNR_MAXFRAMES, param);
       case VP8E_SET_ARNR_STRENGTH:
         return vpx_codec_control(ctx, VP8E_SET_ARNR_STRENGTH, param);
-      case VP8E_SET_ARNR_TYPE:
-        RTC_NOTREACHED() << "VP8E_SET_ARNR_TYPE is deprecated.";
-        return VPX_CODEC_UNSUP_FEATURE;
       case VP8E_SET_CQ_LEVEL:
         return vpx_codec_control(ctx, VP8E_SET_CQ_LEVEL, param);
       case VP8E_SET_MAX_INTRA_BITRATE_PCT:
         return vpx_codec_control(ctx, VP8E_SET_MAX_INTRA_BITRATE_PCT, param);
+      case VP9E_SET_MAX_INTER_BITRATE_PCT:
+        return vpx_codec_control(ctx, VP9E_SET_MAX_INTER_BITRATE_PCT, param);
       case VP8E_SET_GF_CBR_BOOST_PCT:
         return vpx_codec_control(ctx, VP8E_SET_GF_CBR_BOOST_PCT, param);
       case VP8E_SET_SCREEN_CONTENT_MODE:
         return vpx_codec_control(ctx, VP8E_SET_SCREEN_CONTENT_MODE, param);
+      case VP9E_SET_GF_CBR_BOOST_PCT:
+        return vpx_codec_control(ctx, VP9E_SET_GF_CBR_BOOST_PCT, param);
+      case VP9E_SET_LOSSLESS:
+        return vpx_codec_control(ctx, VP9E_SET_LOSSLESS, param);
+      case VP9E_SET_FRAME_PARALLEL_DECODING:
+        return vpx_codec_control(ctx, VP9E_SET_FRAME_PARALLEL_DECODING, param);
+      case VP9E_SET_AQ_MODE:
+        return vpx_codec_control(ctx, VP9E_SET_AQ_MODE, param);
+      case VP9E_SET_FRAME_PERIODIC_BOOST:
+        return vpx_codec_control(ctx, VP9E_SET_FRAME_PERIODIC_BOOST, param);
+      case VP9E_SET_NOISE_SENSITIVITY:
+        return vpx_codec_control(ctx, VP9E_SET_NOISE_SENSITIVITY, param);
+      case VP9E_SET_MIN_GF_INTERVAL:
+        return vpx_codec_control(ctx, VP9E_SET_MIN_GF_INTERVAL, param);
+      case VP9E_SET_MAX_GF_INTERVAL:
+        return vpx_codec_control(ctx, VP9E_SET_MAX_GF_INTERVAL, param);
+      case VP9E_SET_TARGET_LEVEL:
+        return vpx_codec_control(ctx, VP9E_SET_TARGET_LEVEL, param);
+      case VP9E_SET_ROW_MT:
+        return vpx_codec_control(ctx, VP9E_SET_ROW_MT, param);
+      case VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST:
+        return vpx_codec_control(ctx, VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST,
+                                 param);
+      case VP9E_SET_SVC_INTER_LAYER_PRED:
+        return vpx_codec_control(ctx, VP9E_SET_SVC_INTER_LAYER_PRED, param);
+      case VP9E_SET_SVC_GF_TEMPORAL_REF:
+        return vpx_codec_control(ctx, VP9E_SET_SVC_GF_TEMPORAL_REF, param);
+      case VP9E_SET_POSTENCODE_DROP:
+        return vpx_codec_control(ctx, VP9E_SET_POSTENCODE_DROP, param);
       default:
         RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id;
     }
@@ -118,14 +146,41 @@
         return vpx_codec_control(ctx, VP8E_SET_FRAME_FLAGS, param);
       case VP8E_SET_TEMPORAL_LAYER_ID:
         return vpx_codec_control(ctx, VP8E_SET_TEMPORAL_LAYER_ID, param);
+      case VP9E_SET_SVC:
+        return vpx_codec_control(ctx, VP9E_SET_SVC, param);
       case VP8E_SET_CPUUSED:
         return vpx_codec_control(ctx, VP8E_SET_CPUUSED, param);
       case VP8E_SET_TOKEN_PARTITIONS:
         return vpx_codec_control(ctx, VP8E_SET_TOKEN_PARTITIONS, param);
       case VP8E_SET_TUNING:
         return vpx_codec_control(ctx, VP8E_SET_TUNING, param);
+      case VP9E_SET_TILE_COLUMNS:
+        return vpx_codec_control(ctx, VP9E_SET_TILE_COLUMNS, param);
+      case VP9E_SET_TILE_ROWS:
+        return vpx_codec_control(ctx, VP9E_SET_TILE_ROWS, param);
+      case VP9E_SET_TPL:
+        return vpx_codec_control(ctx, VP9E_SET_TPL, param);
+      case VP9E_SET_ALT_REF_AQ:
+        return vpx_codec_control(ctx, VP9E_SET_ALT_REF_AQ, param);
+      case VP9E_SET_TUNE_CONTENT:
+        return vpx_codec_control(ctx, VP9E_SET_TUNE_CONTENT, param);
+      case VP9E_SET_COLOR_SPACE:
+        return vpx_codec_control(ctx, VP9E_SET_COLOR_SPACE, param);
+      case VP9E_SET_COLOR_RANGE:
+        return vpx_codec_control(ctx, VP9E_SET_COLOR_RANGE, param);
+      case VP9E_SET_DELTA_Q_UV:
+        return vpx_codec_control(ctx, VP9E_SET_DELTA_Q_UV, param);
+      case VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR:
+        return vpx_codec_control(ctx, VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR,
+                                 param);
+      case VP9E_SET_DISABLE_LOOPFILTER:
+        return vpx_codec_control(ctx, VP9E_SET_DISABLE_LOOPFILTER, param);
 
       default:
+        if (param >= 0) {
+          // Might be intended for uint32_t but int literal used, try fallback.
+          return codec_control(ctx, ctrl_id, static_cast<uint32_t>(param));
+        }
         RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id;
     }
     return VPX_CODEC_ERROR;
@@ -139,6 +194,10 @@
         return vpx_codec_control(ctx, VP8E_GET_LAST_QUANTIZER, param);
       case VP8E_GET_LAST_QUANTIZER_64:
         return vpx_codec_control(ctx, VP8E_GET_LAST_QUANTIZER_64, param);
+      case VP9E_SET_RENDER_SIZE:
+        return vpx_codec_control(ctx, VP9E_SET_RENDER_SIZE, param);
+      case VP9E_GET_LEVEL:
+        return vpx_codec_control(ctx, VP9E_GET_LEVEL, param);
       default:
         RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id;
     }
@@ -151,6 +210,8 @@
     switch (ctrl_id) {
       case VP8E_SET_ROI_MAP:
         return vpx_codec_control(ctx, VP8E_SET_ROI_MAP, param);
+      case VP9E_SET_ROI_MAP:
+        return vpx_codec_control(ctx, VP9E_SET_ROI_MAP, param);
       default:
         RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id;
     }
@@ -163,6 +224,8 @@
     switch (ctrl_id) {
       case VP8E_SET_ACTIVEMAP:
         return vpx_codec_control(ctx, VP8E_SET_ACTIVEMAP, param);
+      case VP9E_GET_ACTIVEMAP:
+        return vpx_codec_control(ctx, VP8E_SET_ACTIVEMAP, param);
       default:
         RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id;
     }
@@ -181,6 +244,98 @@
     return VPX_CODEC_ERROR;
   }
 
+  vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx,
+                                vp8e_enc_control_id ctrl_id,
+                                vpx_svc_extra_cfg_t* param) const override {
+    switch (ctrl_id) {
+      case VP9E_SET_SVC_PARAMETERS:
+        return vpx_codec_control_(ctx, VP9E_SET_SVC_PARAMETERS, param);
+      default:
+        RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id;
+    }
+    return VPX_CODEC_ERROR;
+  }
+
+  vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx,
+                                vp8e_enc_control_id ctrl_id,
+                                vpx_svc_frame_drop_t* param) const override {
+    switch (ctrl_id) {
+      case VP9E_SET_SVC_FRAME_DROP_LAYER:
+        return vpx_codec_control_(ctx, VP9E_SET_SVC_FRAME_DROP_LAYER, param);
+      default:
+        RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id;
+    }
+    return VPX_CODEC_ERROR;
+  }
+
+  vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx,
+                                vp8e_enc_control_id ctrl_id,
+                                void* param) const override {
+    switch (ctrl_id) {
+      case VP9E_SET_SVC_PARAMETERS:
+        return vpx_codec_control_(ctx, VP9E_SET_SVC_PARAMETERS, param);
+      case VP9E_REGISTER_CX_CALLBACK:
+        return vpx_codec_control_(ctx, VP9E_REGISTER_CX_CALLBACK, param);
+      default:
+        RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id;
+    }
+    return VPX_CODEC_ERROR;
+  }
+
+  vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx,
+                                vp8e_enc_control_id ctrl_id,
+                                vpx_svc_layer_id_t* param) const override {
+    switch (ctrl_id) {
+      case VP9E_SET_SVC_LAYER_ID:
+        return vpx_codec_control_(ctx, VP9E_SET_SVC_LAYER_ID, param);
+      case VP9E_GET_SVC_LAYER_ID:
+        return vpx_codec_control_(ctx, VP9E_GET_SVC_LAYER_ID, param);
+      default:
+        RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id;
+    }
+    return VPX_CODEC_ERROR;
+  }
+
+  vpx_codec_err_t codec_control(
+      vpx_codec_ctx_t* ctx,
+      vp8e_enc_control_id ctrl_id,
+      vpx_svc_ref_frame_config_t* param) const override {
+    switch (ctrl_id) {
+      case VP9E_SET_SVC_REF_FRAME_CONFIG:
+        return vpx_codec_control_(ctx, VP9E_SET_SVC_REF_FRAME_CONFIG, param);
+      case VP9E_GET_SVC_REF_FRAME_CONFIG:
+        return vpx_codec_control_(ctx, VP9E_GET_SVC_REF_FRAME_CONFIG, param);
+      default:
+        RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id;
+    }
+    return VPX_CODEC_ERROR;
+  }
+
+  vpx_codec_err_t codec_control(
+      vpx_codec_ctx_t* ctx,
+      vp8e_enc_control_id ctrl_id,
+      vpx_svc_spatial_layer_sync_t* param) const override {
+    switch (ctrl_id) {
+      case VP9E_SET_SVC_SPATIAL_LAYER_SYNC:
+        return vpx_codec_control_(ctx, VP9E_SET_SVC_SPATIAL_LAYER_SYNC, param);
+      default:
+        RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id;
+    }
+    return VPX_CODEC_ERROR;
+  }
+
+  vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx,
+                                vp8e_enc_control_id ctrl_id,
+                                vpx_rc_funcs_t* param) const override {
+    switch (ctrl_id) {
+      case VP9E_SET_EXTERNAL_RATE_CONTROL:
+        return vpx_codec_control_(ctx, VP9E_SET_EXTERNAL_RATE_CONTROL, param);
+      default:
+        RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id;
+    }
+    return VPX_CODEC_ERROR;
+  }
+
   vpx_codec_err_t codec_encode(vpx_codec_ctx_t* ctx,
                                const vpx_image_t* img,
                                vpx_codec_pts_t pts,
@@ -199,6 +354,14 @@
   const char* codec_error_detail(vpx_codec_ctx_t* ctx) const override {
     return ::vpx_codec_error_detail(ctx);
   }
+
+  const char* codec_error(vpx_codec_ctx_t* ctx) const override {
+    return ::vpx_codec_error(ctx);
+  }
+
+  const char* codec_err_to_string(vpx_codec_err_t err) const override {
+    return ::vpx_codec_err_to_string(err);
+  }
 };
 
 }  // namespace
diff --git a/modules/video_coding/codecs/interface/libvpx_interface.h b/modules/video_coding/codecs/interface/libvpx_interface.h
index f087ff3..3dea24d 100644
--- a/modules/video_coding/codecs/interface/libvpx_interface.h
+++ b/modules/video_coding/codecs/interface/libvpx_interface.h
@@ -81,7 +81,29 @@
   virtual vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx,
                                         vp8e_enc_control_id ctrl_id,
                                         vpx_scaling_mode* param) const = 0;
-
+  virtual vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx,
+                                        vp8e_enc_control_id ctrl_id,
+                                        vpx_svc_extra_cfg_t* param) const = 0;
+  virtual vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx,
+                                        vp8e_enc_control_id ctrl_id,
+                                        vpx_svc_frame_drop_t* param) const = 0;
+  virtual vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx,
+                                        vp8e_enc_control_id ctrl_id,
+                                        void* param) const = 0;
+  virtual vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx,
+                                        vp8e_enc_control_id ctrl_id,
+                                        vpx_svc_layer_id_t* param) const = 0;
+  virtual vpx_codec_err_t codec_control(
+      vpx_codec_ctx_t* ctx,
+      vp8e_enc_control_id ctrl_id,
+      vpx_svc_ref_frame_config_t* param) const = 0;
+  virtual vpx_codec_err_t codec_control(
+      vpx_codec_ctx_t* ctx,
+      vp8e_enc_control_id ctrl_id,
+      vpx_svc_spatial_layer_sync_t* param) const = 0;
+  virtual vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx,
+                                        vp8e_enc_control_id ctrl_id,
+                                        vpx_rc_funcs_t* param) const = 0;
   virtual vpx_codec_err_t codec_encode(vpx_codec_ctx_t* ctx,
                                        const vpx_image_t* img,
                                        vpx_codec_pts_t pts,
@@ -94,6 +116,8 @@
       vpx_codec_iter_t* iter) const = 0;
 
   virtual const char* codec_error_detail(vpx_codec_ctx_t* ctx) const = 0;
+  virtual const char* codec_error(vpx_codec_ctx_t* ctx) const = 0;
+  virtual const char* codec_err_to_string(vpx_codec_err_t err) const = 0;
 
   // Returns interface wrapping the actual libvpx functions.
   static std::unique_ptr<LibvpxInterface> Create();
diff --git a/modules/video_coding/codecs/interface/mock_libvpx_interface.h b/modules/video_coding/codecs/interface/mock_libvpx_interface.h
index 33681cb..6dfe733 100644
--- a/modules/video_coding/codecs/interface/mock_libvpx_interface.h
+++ b/modules/video_coding/codecs/interface/mock_libvpx_interface.h
@@ -87,6 +87,38 @@
               (vpx_codec_ctx_t*, vp8e_enc_control_id, vpx_scaling_mode*),
               (const, override));
   MOCK_METHOD(vpx_codec_err_t,
+              codec_control,
+              (vpx_codec_ctx_t*, vp8e_enc_control_id, vpx_svc_extra_cfg_t*),
+              (const, override));
+  MOCK_METHOD(vpx_codec_err_t,
+              codec_control,
+              (vpx_codec_ctx_t*, vp8e_enc_control_id, vpx_svc_frame_drop_t*),
+              (const, override));
+  MOCK_METHOD(vpx_codec_err_t,
+              codec_control,
+              (vpx_codec_ctx_t*, vp8e_enc_control_id, void*),
+              (const, override));
+  MOCK_METHOD(vpx_codec_err_t,
+              codec_control,
+              (vpx_codec_ctx_t*, vp8e_enc_control_id, vpx_svc_layer_id_t*),
+              (const, override));
+  MOCK_METHOD(vpx_codec_err_t,
+              codec_control,
+              (vpx_codec_ctx_t*,
+               vp8e_enc_control_id,
+               vpx_svc_ref_frame_config_t*),
+              (const, override));
+  MOCK_METHOD(vpx_codec_err_t,
+              codec_control,
+              (vpx_codec_ctx_t*,
+               vp8e_enc_control_id,
+               vpx_svc_spatial_layer_sync_t*),
+              (const, override));
+  MOCK_METHOD(vpx_codec_err_t,
+              codec_control,
+              (vpx_codec_ctx_t*, vp8e_enc_control_id, vpx_rc_funcs_t*),
+              (const, override));
+  MOCK_METHOD(vpx_codec_err_t,
               codec_encode,
               (vpx_codec_ctx_t*,
                const vpx_image_t*,
@@ -103,6 +135,11 @@
               codec_error_detail,
               (vpx_codec_ctx_t*),
               (const, override));
+  MOCK_METHOD(const char*, codec_error, (vpx_codec_ctx_t*), (const, override));
+  MOCK_METHOD(const char*,
+              codec_err_to_string,
+              (vpx_codec_err_t),
+              (const, override));
 };
 
 }  // namespace webrtc
diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
index 2f2fa6c..0e3991b 100644
--- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
+++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
@@ -257,7 +257,7 @@
 
   if (encoder_ != nullptr) {
     if (inited_) {
-      if (vpx_codec_destroy(encoder_)) {
+      if (libvpx_->codec_destroy(encoder_)) {
         ret_val = WEBRTC_VIDEO_CODEC_MEMORY;
       }
     }
@@ -269,7 +269,7 @@
     config_ = nullptr;
   }
   if (raw_ != nullptr) {
-    vpx_img_free(raw_);
+    libvpx_->img_free(raw_);
     raw_ = nullptr;
   }
   inited_ = false;
@@ -501,7 +501,7 @@
   is_svc_ = (num_spatial_layers_ > 1 || num_temporal_layers_ > 1);
 
   // Populate encoder configuration with default values.
-  if (vpx_codec_enc_config_default(vpx_codec_vp9_cx(), config_, 0)) {
+  if (libvpx_->codec_enc_config_default(vpx_codec_vp9_cx(), config_, 0)) {
     return WEBRTC_VIDEO_CODEC_ERROR;
   }
 
@@ -532,8 +532,8 @@
   // Creating a wrapper to the image - setting image data to nullptr. Actual
   // pointer will be set in encode. Setting align to 1, as it is meaningless
   // (actual memory is not allocated).
-  raw_ =
-      vpx_img_wrap(nullptr, img_fmt, codec_.width, codec_.height, 1, nullptr);
+  raw_ = libvpx_->img_wrap(nullptr, img_fmt, codec_.width, codec_.height, 1,
+                           nullptr);
   raw_->bit_depth = bits_for_storage;
 
   config_->g_w = codec_.width;
@@ -728,11 +728,11 @@
     return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
   }
 
-  const vpx_codec_err_t rv = vpx_codec_enc_init(
+  const vpx_codec_err_t rv = libvpx_->codec_enc_init(
       encoder_, vpx_codec_vp9_cx(), config_,
       config_->g_bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH);
   if (rv != VPX_CODEC_OK) {
-    RTC_LOG(LS_ERROR) << "Init error: " << vpx_codec_err_to_string(rv);
+    RTC_LOG(LS_ERROR) << "Init error: " << libvpx_->codec_err_to_string(rv);
     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
   }
 
@@ -748,20 +748,20 @@
     }
   }
 
-  vpx_codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT,
-                    rc_max_intra_target_);
-  vpx_codec_control(encoder_, VP9E_SET_AQ_MODE,
-                    inst->VP9().adaptiveQpMode ? 3 : 0);
+  libvpx_->codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT,
+                         rc_max_intra_target_);
+  libvpx_->codec_control(encoder_, VP9E_SET_AQ_MODE,
+                         inst->VP9().adaptiveQpMode ? 3 : 0);
 
-  vpx_codec_control(encoder_, VP9E_SET_FRAME_PARALLEL_DECODING, 0);
-  vpx_codec_control(encoder_, VP9E_SET_SVC_GF_TEMPORAL_REF, 0);
+  libvpx_->codec_control(encoder_, VP9E_SET_FRAME_PARALLEL_DECODING, 0);
+  libvpx_->codec_control(encoder_, VP9E_SET_SVC_GF_TEMPORAL_REF, 0);
 
   if (is_svc_) {
-    vpx_codec_control(encoder_, VP9E_SET_SVC, 1);
-    vpx_codec_control(encoder_, VP9E_SET_SVC_PARAMETERS, &svc_params_);
+    libvpx_->codec_control(encoder_, VP9E_SET_SVC, 1);
+    libvpx_->codec_control(encoder_, VP9E_SET_SVC_PARAMETERS, &svc_params_);
   }
   if (!performance_flags_.use_per_layer_speed) {
-    vpx_codec_control(
+    libvpx_->codec_control(
         encoder_, VP8E_SET_CPUUSED,
         performance_flags_by_spatial_index_.rbegin()->base_layer_speed);
   }
@@ -769,13 +769,13 @@
   if (num_spatial_layers_ > 1) {
     switch (inter_layer_pred_) {
       case InterLayerPredMode::kOn:
-        vpx_codec_control(encoder_, VP9E_SET_SVC_INTER_LAYER_PRED, 0);
+        libvpx_->codec_control(encoder_, VP9E_SET_SVC_INTER_LAYER_PRED, 0);
         break;
       case InterLayerPredMode::kOff:
-        vpx_codec_control(encoder_, VP9E_SET_SVC_INTER_LAYER_PRED, 1);
+        libvpx_->codec_control(encoder_, VP9E_SET_SVC_INTER_LAYER_PRED, 1);
         break;
       case InterLayerPredMode::kOnKeyPic:
-        vpx_codec_control(encoder_, VP9E_SET_SVC_INTER_LAYER_PRED, 2);
+        libvpx_->codec_control(encoder_, VP9E_SET_SVC_INTER_LAYER_PRED, 2);
         break;
       default:
         RTC_NOTREACHED();
@@ -812,40 +812,41 @@
         svc_drop_frame_.framedrop_thresh[i] = config_->rc_dropframe_thresh;
       }
     }
-    vpx_codec_control(encoder_, VP9E_SET_SVC_FRAME_DROP_LAYER,
-                      &svc_drop_frame_);
+    libvpx_->codec_control(encoder_, VP9E_SET_SVC_FRAME_DROP_LAYER,
+                           &svc_drop_frame_);
   }
 
   // Register callback for getting each spatial layer.
   vpx_codec_priv_output_cx_pkt_cb_pair_t cbp = {
       LibvpxVp9Encoder::EncoderOutputCodedPacketCallback,
       reinterpret_cast<void*>(this)};
-  vpx_codec_control(encoder_, VP9E_REGISTER_CX_CALLBACK,
-                    reinterpret_cast<void*>(&cbp));
+  libvpx_->codec_control(encoder_, VP9E_REGISTER_CX_CALLBACK,
+                         reinterpret_cast<void*>(&cbp));
 
   // Control function to set the number of column tiles in encoding a frame, in
   // log2 unit: e.g., 0 = 1 tile column, 1 = 2 tile columns, 2 = 4 tile columns.
   // The number tile columns will be capped by the encoder based on image size
   // (minimum width of tile column is 256 pixels, maximum is 4096).
-  vpx_codec_control(encoder_, VP9E_SET_TILE_COLUMNS, (config_->g_threads >> 1));
+  libvpx_->codec_control(encoder_, VP9E_SET_TILE_COLUMNS,
+                         static_cast<int>((config_->g_threads >> 1)));
 
   // Turn on row-based multithreading.
-  vpx_codec_control(encoder_, VP9E_SET_ROW_MT, 1);
+  libvpx_->codec_control(encoder_, VP9E_SET_ROW_MT, 1);
 
 #if !defined(WEBRTC_ARCH_ARM) && !defined(WEBRTC_ARCH_ARM64) && \
     !defined(ANDROID)
   // Do not enable the denoiser on ARM since optimization is pending.
   // Denoiser is on by default on other platforms.
-  vpx_codec_control(encoder_, VP9E_SET_NOISE_SENSITIVITY,
-                    inst->VP9().denoisingOn ? 1 : 0);
+  libvpx_->codec_control(encoder_, VP9E_SET_NOISE_SENSITIVITY,
+                         inst->VP9().denoisingOn ? 1 : 0);
 #endif
 
   if (codec_.mode == VideoCodecMode::kScreensharing) {
     // Adjust internal parameters to screen content.
-    vpx_codec_control(encoder_, VP9E_SET_TUNE_CONTENT, 1);
+    libvpx_->codec_control(encoder_, VP9E_SET_TUNE_CONTENT, 1);
   }
   // Enable encoder skip of static/low content blocks.
-  vpx_codec_control(encoder_, VP8E_SET_STATIC_THRESHOLD, 1);
+  libvpx_->codec_control(encoder_, VP8E_SET_STATIC_THRESHOLD, 1);
   inited_ = true;
   config_changed_ = true;
   return WEBRTC_VIDEO_CODEC_OK;
@@ -992,20 +993,20 @@
       }
     }
     if (speed_updated) {
-      vpx_codec_control(encoder_, VP9E_SET_SVC_PARAMETERS, &svc_params_);
+      libvpx_->codec_control(encoder_, VP9E_SET_SVC_PARAMETERS, &svc_params_);
     }
   }
 
-  vpx_codec_control(encoder_, VP9E_SET_SVC_LAYER_ID, &layer_id);
+  libvpx_->codec_control(encoder_, VP9E_SET_SVC_LAYER_ID, &layer_id);
 
   if (num_spatial_layers_ > 1) {
     // Update frame dropping settings as they may change on per-frame basis.
-    vpx_codec_control(encoder_, VP9E_SET_SVC_FRAME_DROP_LAYER,
-                      &svc_drop_frame_);
+    libvpx_->codec_control(encoder_, VP9E_SET_SVC_FRAME_DROP_LAYER,
+                           &svc_drop_frame_);
   }
 
   if (config_changed_) {
-    if (vpx_codec_enc_config_set(encoder_, config_)) {
+    if (libvpx_->codec_enc_config_set(encoder_, config_)) {
       return WEBRTC_VIDEO_CODEC_ERROR;
     }
 
@@ -1022,7 +1023,7 @@
               std::prev(performance_flags_.settings_by_resolution.lower_bound(
                             width * height))
                   ->second.base_layer_speed;
-          vpx_codec_control(encoder_, VP8E_SET_CPUUSED, speed);
+          libvpx_->codec_control(encoder_, VP8E_SET_CPUUSED, speed);
           break;
         }
       }
@@ -1111,7 +1112,8 @@
 
   if (svc_controller_) {
     vpx_svc_ref_frame_config_t ref_config = Vp9References(layer_frames_);
-    vpx_codec_control(encoder_, VP9E_SET_SVC_REF_FRAME_CONFIG, &ref_config);
+    libvpx_->codec_control(encoder_, VP9E_SET_SVC_REF_FRAME_CONFIG,
+                           &ref_config);
   } else if (external_ref_control_) {
     vpx_svc_ref_frame_config_t ref_config =
         SetReferences(force_key_frame_, layer_id.spatial_layer_id);
@@ -1124,7 +1126,8 @@
       }
     }
 
-    vpx_codec_control(encoder_, VP9E_SET_SVC_REF_FRAME_CONFIG, &ref_config);
+    libvpx_->codec_control(encoder_, VP9E_SET_SVC_REF_FRAME_CONFIG,
+                           &ref_config);
   }
 
   first_frame_in_picture_ = true;
@@ -1144,14 +1147,14 @@
                          .GetTargetRate())
           : codec_.maxFramerate;
   uint32_t duration = static_cast<uint32_t>(90000 / target_framerate_fps);
-  const vpx_codec_err_t rv = vpx_codec_encode(encoder_, raw_, timestamp_,
-                                              duration, flags, VPX_DL_REALTIME);
+  const vpx_codec_err_t rv = libvpx_->codec_encode(
+      encoder_, raw_, timestamp_, duration, flags, VPX_DL_REALTIME);
   if (rv != VPX_CODEC_OK) {
-    RTC_LOG(LS_ERROR) << "Encoding error: " << vpx_codec_err_to_string(rv)
+    RTC_LOG(LS_ERROR) << "Encoding error: " << libvpx_->codec_err_to_string(rv)
                       << "\n"
                          "Details: "
-                      << vpx_codec_error(encoder_) << "\n"
-                      << vpx_codec_error_detail(encoder_);
+                      << libvpx_->codec_error(encoder_) << "\n"
+                      << libvpx_->codec_error_detail(encoder_);
     return WEBRTC_VIDEO_CODEC_ERROR;
   }
   timestamp_ += duration;
@@ -1182,7 +1185,7 @@
   }
 
   vpx_svc_layer_id_t layer_id = {0};
-  vpx_codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id);
+  libvpx_->codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id);
 
   // Can't have keyframe with non-zero temporal layer.
   RTC_DCHECK(pics_since_key_ != 0 || layer_id.temporal_layer_id == 0);
@@ -1310,7 +1313,7 @@
                                             const bool inter_layer_predicted,
                                             CodecSpecificInfoVP9* vp9_info) {
   vpx_svc_layer_id_t layer_id = {0};
-  vpx_codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id);
+  libvpx_->codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id);
 
   const bool is_key_frame =
       (pkt.data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
@@ -1319,7 +1322,8 @@
 
   if (is_svc_) {
     vpx_svc_ref_frame_config_t enc_layer_conf = {{0}};
-    vpx_codec_control(encoder_, VP9E_GET_SVC_REF_FRAME_CONFIG, &enc_layer_conf);
+    libvpx_->codec_control(encoder_, VP9E_GET_SVC_REF_FRAME_CONFIG,
+                           &enc_layer_conf);
     int ref_buf_flags = 0;
 
     if (enc_layer_conf.reference_last[layer_id.spatial_layer_id]) {
@@ -1427,14 +1431,15 @@
 void LibvpxVp9Encoder::UpdateReferenceBuffers(const vpx_codec_cx_pkt& pkt,
                                               const size_t pic_num) {
   vpx_svc_layer_id_t layer_id = {0};
-  vpx_codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id);
+  libvpx_->codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id);
 
   RefFrameBuffer frame_buf(pic_num, layer_id.spatial_layer_id,
                            layer_id.temporal_layer_id);
 
   if (is_svc_) {
     vpx_svc_ref_frame_config_t enc_layer_conf = {{0}};
-    vpx_codec_control(encoder_, VP9E_GET_SVC_REF_FRAME_CONFIG, &enc_layer_conf);
+    libvpx_->codec_control(encoder_, VP9E_GET_SVC_REF_FRAME_CONFIG,
+                           &enc_layer_conf);
     const int update_buffer_slot =
         enc_layer_conf.update_buffer_slot[layer_id.spatial_layer_id];
 
@@ -1567,7 +1572,7 @@
   }
 
   vpx_svc_layer_id_t layer_id = {0};
-  vpx_codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id);
+  libvpx_->codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id);
 
   if (layer_buffering_) {
     // Deliver buffered low spatial layer frame.
@@ -1607,7 +1612,7 @@
   encoded_image_._encodedWidth =
       pkt->data.frame.width[layer_id.spatial_layer_id];
   int qp = -1;
-  vpx_codec_control(encoder_, VP8E_GET_LAST_QUANTIZER, &qp);
+  libvpx_->codec_control(encoder_, VP8E_GET_LAST_QUANTIZER, &qp);
   encoded_image_.qp_ = qp;
 
   if (!layer_buffering_) {
@@ -1863,12 +1868,14 @@
 
 void LibvpxVp9Encoder::MaybeRewrapRawWithFormat(const vpx_img_fmt fmt) {
   if (!raw_) {
-    raw_ = vpx_img_wrap(nullptr, fmt, codec_.width, codec_.height, 1, nullptr);
+    raw_ = libvpx_->img_wrap(nullptr, fmt, codec_.width, codec_.height, 1,
+                             nullptr);
   } else if (raw_->fmt != fmt) {
     RTC_LOG(INFO) << "Switching VP9 encoder pixel format to "
                   << (fmt == VPX_IMG_FMT_NV12 ? "NV12" : "I420");
-    vpx_img_free(raw_);
-    raw_ = vpx_img_wrap(nullptr, fmt, codec_.width, codec_.height, 1, nullptr);
+    libvpx_->img_free(raw_);
+    raw_ = libvpx_->img_wrap(nullptr, fmt, codec_.width, codec_.height, 1,
+                             nullptr);
   }
   // else no-op since the image is already in the right format.
 }