libvpx_interface.cc (15484B)
1 /* 2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "modules/video_coding/codecs/interface/libvpx_interface.h" 12 13 #include <cstdint> 14 #include <memory> 15 16 #include "rtc_base/checks.h" 17 #include "third_party/libvpx/source/libvpx/vpx/vp8cx.h" 18 #include "third_party/libvpx/source/libvpx/vpx/vpx_codec.h" 19 #include "third_party/libvpx/source/libvpx/vpx/vpx_encoder.h" 20 #include "third_party/libvpx/source/libvpx/vpx/vpx_ext_ratectrl.h" 21 #include "third_party/libvpx/source/libvpx/vpx/vpx_image.h" 22 23 namespace webrtc { 24 namespace { 25 class LibvpxFacade : public LibvpxInterface { 26 public: 27 LibvpxFacade() = default; 28 ~LibvpxFacade() override = default; 29 30 vpx_image_t* img_alloc(vpx_image_t* img, 31 vpx_img_fmt_t fmt, 32 unsigned int d_w, 33 unsigned int d_h, 34 unsigned int align) const override { 35 return ::vpx_img_alloc(img, fmt, d_w, d_h, align); 36 } 37 38 vpx_image_t* img_wrap(vpx_image_t* img, 39 vpx_img_fmt_t fmt, 40 unsigned int d_w, 41 unsigned int d_h, 42 unsigned int stride_align, 43 unsigned char* img_data) const override { 44 return ::vpx_img_wrap(img, fmt, d_w, d_h, stride_align, img_data); 45 } 46 47 void img_free(vpx_image_t* img) const override { ::vpx_img_free(img); } 48 49 vpx_codec_err_t codec_enc_config_set( 50 vpx_codec_ctx_t* ctx, 51 const vpx_codec_enc_cfg_t* cfg) const override { 52 return ::vpx_codec_enc_config_set(ctx, cfg); 53 } 54 55 vpx_codec_err_t codec_enc_config_default(vpx_codec_iface_t* iface, 56 vpx_codec_enc_cfg_t* cfg, 57 unsigned int usage) const override { 58 return ::vpx_codec_enc_config_default(iface, cfg, usage); 59 } 60 61 vpx_codec_err_t codec_enc_init(vpx_codec_ctx_t* ctx, 62 vpx_codec_iface_t* iface, 63 const vpx_codec_enc_cfg_t* cfg, 64 vpx_codec_flags_t flags) const override { 65 return ::vpx_codec_enc_init(ctx, iface, cfg, flags); 66 } 67 68 vpx_codec_err_t codec_enc_init_multi(vpx_codec_ctx_t* ctx, 69 vpx_codec_iface_t* iface, 70 vpx_codec_enc_cfg_t* cfg, 71 int num_enc, 72 vpx_codec_flags_t flags, 73 vpx_rational_t* dsf) const override { 74 return ::vpx_codec_enc_init_multi(ctx, iface, cfg, num_enc, flags, dsf); 75 } 76 77 vpx_codec_err_t codec_destroy(vpx_codec_ctx_t* ctx) const override { 78 return ::vpx_codec_destroy(ctx); 79 } 80 81 // For types related to these parameters, see section 82 // "VP8 encoder control function parameter type" in vpx/vp8cx.h. 83 84 vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, 85 vp8e_enc_control_id ctrl_id, 86 uint32_t param) const override { 87 // We need an explicit call for each type since vpx_codec_control is a 88 // macro that gets expanded into another call based on the parameter name. 89 switch (ctrl_id) { 90 case VP8E_SET_ENABLEAUTOALTREF: 91 return vpx_codec_control(ctx, VP8E_SET_ENABLEAUTOALTREF, param); 92 case VP8E_SET_NOISE_SENSITIVITY: 93 return vpx_codec_control(ctx, VP8E_SET_NOISE_SENSITIVITY, param); 94 case VP8E_SET_SHARPNESS: 95 return vpx_codec_control(ctx, VP8E_SET_SHARPNESS, param); 96 case VP8E_SET_STATIC_THRESHOLD: 97 return vpx_codec_control(ctx, VP8E_SET_STATIC_THRESHOLD, param); 98 case VP8E_SET_ARNR_MAXFRAMES: 99 return vpx_codec_control(ctx, VP8E_SET_ARNR_MAXFRAMES, param); 100 case VP8E_SET_ARNR_STRENGTH: 101 return vpx_codec_control(ctx, VP8E_SET_ARNR_STRENGTH, param); 102 case VP8E_SET_CQ_LEVEL: 103 return vpx_codec_control(ctx, VP8E_SET_CQ_LEVEL, param); 104 case VP8E_SET_MAX_INTRA_BITRATE_PCT: 105 return vpx_codec_control(ctx, VP8E_SET_MAX_INTRA_BITRATE_PCT, param); 106 case VP9E_SET_MAX_INTER_BITRATE_PCT: 107 return vpx_codec_control(ctx, VP9E_SET_MAX_INTER_BITRATE_PCT, param); 108 case VP8E_SET_GF_CBR_BOOST_PCT: 109 return vpx_codec_control(ctx, VP8E_SET_GF_CBR_BOOST_PCT, param); 110 case VP8E_SET_SCREEN_CONTENT_MODE: 111 return vpx_codec_control(ctx, VP8E_SET_SCREEN_CONTENT_MODE, param); 112 case VP9E_SET_GF_CBR_BOOST_PCT: 113 return vpx_codec_control(ctx, VP9E_SET_GF_CBR_BOOST_PCT, param); 114 case VP9E_SET_LOSSLESS: 115 return vpx_codec_control(ctx, VP9E_SET_LOSSLESS, param); 116 case VP9E_SET_FRAME_PARALLEL_DECODING: 117 return vpx_codec_control(ctx, VP9E_SET_FRAME_PARALLEL_DECODING, param); 118 case VP9E_SET_AQ_MODE: 119 return vpx_codec_control(ctx, VP9E_SET_AQ_MODE, param); 120 case VP9E_SET_FRAME_PERIODIC_BOOST: 121 return vpx_codec_control(ctx, VP9E_SET_FRAME_PERIODIC_BOOST, param); 122 case VP9E_SET_NOISE_SENSITIVITY: 123 return vpx_codec_control(ctx, VP9E_SET_NOISE_SENSITIVITY, param); 124 case VP9E_SET_MIN_GF_INTERVAL: 125 return vpx_codec_control(ctx, VP9E_SET_MIN_GF_INTERVAL, param); 126 case VP9E_SET_MAX_GF_INTERVAL: 127 return vpx_codec_control(ctx, VP9E_SET_MAX_GF_INTERVAL, param); 128 case VP9E_SET_TARGET_LEVEL: 129 return vpx_codec_control(ctx, VP9E_SET_TARGET_LEVEL, param); 130 case VP9E_SET_ROW_MT: 131 return vpx_codec_control(ctx, VP9E_SET_ROW_MT, param); 132 case VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST: 133 return vpx_codec_control(ctx, VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, 134 param); 135 case VP9E_SET_SVC_INTER_LAYER_PRED: 136 return vpx_codec_control(ctx, VP9E_SET_SVC_INTER_LAYER_PRED, param); 137 case VP9E_SET_SVC_GF_TEMPORAL_REF: 138 return vpx_codec_control(ctx, VP9E_SET_SVC_GF_TEMPORAL_REF, param); 139 case VP9E_SET_POSTENCODE_DROP: 140 return vpx_codec_control(ctx, VP9E_SET_POSTENCODE_DROP, param); 141 default: 142 RTC_DCHECK_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; 143 } 144 return VPX_CODEC_ERROR; 145 } 146 147 vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, 148 vp8e_enc_control_id ctrl_id, 149 int param) const override { 150 switch (ctrl_id) { 151 case VP8E_SET_FRAME_FLAGS: 152 return vpx_codec_control(ctx, VP8E_SET_FRAME_FLAGS, param); 153 case VP8E_SET_TEMPORAL_LAYER_ID: 154 return vpx_codec_control(ctx, VP8E_SET_TEMPORAL_LAYER_ID, param); 155 case VP9E_SET_SVC: 156 return vpx_codec_control(ctx, VP9E_SET_SVC, param); 157 case VP8E_SET_CPUUSED: 158 return vpx_codec_control(ctx, VP8E_SET_CPUUSED, param); 159 case VP8E_SET_TOKEN_PARTITIONS: 160 return vpx_codec_control(ctx, VP8E_SET_TOKEN_PARTITIONS, param); 161 case VP8E_SET_TUNING: 162 return vpx_codec_control(ctx, VP8E_SET_TUNING, param); 163 case VP9E_SET_TILE_COLUMNS: 164 return vpx_codec_control(ctx, VP9E_SET_TILE_COLUMNS, param); 165 case VP9E_SET_TILE_ROWS: 166 return vpx_codec_control(ctx, VP9E_SET_TILE_ROWS, param); 167 case VP9E_SET_TPL: 168 return vpx_codec_control(ctx, VP9E_SET_TPL, param); 169 case VP9E_SET_ALT_REF_AQ: 170 return vpx_codec_control(ctx, VP9E_SET_ALT_REF_AQ, param); 171 case VP9E_SET_TUNE_CONTENT: 172 return vpx_codec_control(ctx, VP9E_SET_TUNE_CONTENT, param); 173 case VP9E_SET_COLOR_SPACE: 174 return vpx_codec_control(ctx, VP9E_SET_COLOR_SPACE, param); 175 case VP9E_SET_COLOR_RANGE: 176 return vpx_codec_control(ctx, VP9E_SET_COLOR_RANGE, param); 177 case VP9E_SET_DELTA_Q_UV: 178 return vpx_codec_control(ctx, VP9E_SET_DELTA_Q_UV, param); 179 case VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR: 180 return vpx_codec_control(ctx, VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, 181 param); 182 case VP9E_SET_DISABLE_LOOPFILTER: 183 return vpx_codec_control(ctx, VP9E_SET_DISABLE_LOOPFILTER, param); 184 185 default: 186 if (param >= 0) { 187 // Might be intended for uint32_t but int literal used, try fallback. 188 return codec_control(ctx, ctrl_id, static_cast<uint32_t>(param)); 189 } 190 RTC_DCHECK_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; 191 } 192 return VPX_CODEC_ERROR; 193 } 194 195 vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, 196 vp8e_enc_control_id ctrl_id, 197 int* param) const override { 198 switch (ctrl_id) { 199 case VP8E_GET_LAST_QUANTIZER: 200 return vpx_codec_control(ctx, VP8E_GET_LAST_QUANTIZER, param); 201 case VP8E_GET_LAST_QUANTIZER_64: 202 return vpx_codec_control(ctx, VP8E_GET_LAST_QUANTIZER_64, param); 203 case VP9E_SET_RENDER_SIZE: 204 return vpx_codec_control(ctx, VP9E_SET_RENDER_SIZE, param); 205 case VP9E_GET_LEVEL: 206 return vpx_codec_control(ctx, VP9E_GET_LEVEL, param); 207 default: 208 RTC_DCHECK_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; 209 } 210 return VPX_CODEC_ERROR; 211 } 212 213 vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, 214 vp8e_enc_control_id ctrl_id, 215 vpx_roi_map* param) const override { 216 switch (ctrl_id) { 217 case VP8E_SET_ROI_MAP: 218 return vpx_codec_control(ctx, VP8E_SET_ROI_MAP, param); 219 case VP9E_SET_ROI_MAP: 220 return vpx_codec_control(ctx, VP9E_SET_ROI_MAP, param); 221 default: 222 RTC_DCHECK_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; 223 } 224 return VPX_CODEC_ERROR; 225 } 226 227 vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, 228 vp8e_enc_control_id ctrl_id, 229 vpx_active_map* param) const override { 230 switch (ctrl_id) { 231 case VP8E_SET_ACTIVEMAP: 232 return vpx_codec_control(ctx, VP8E_SET_ACTIVEMAP, param); 233 case VP9E_GET_ACTIVEMAP: 234 return vpx_codec_control(ctx, VP8E_SET_ACTIVEMAP, param); 235 default: 236 RTC_DCHECK_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; 237 } 238 return VPX_CODEC_ERROR; 239 } 240 241 vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, 242 vp8e_enc_control_id ctrl_id, 243 vpx_scaling_mode* param) const override { 244 switch (ctrl_id) { 245 case VP8E_SET_SCALEMODE: 246 return vpx_codec_control(ctx, VP8E_SET_SCALEMODE, param); 247 default: 248 RTC_DCHECK_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; 249 } 250 return VPX_CODEC_ERROR; 251 } 252 253 vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, 254 vp8e_enc_control_id ctrl_id, 255 vpx_svc_extra_cfg_t* param) const override { 256 switch (ctrl_id) { 257 case VP9E_SET_SVC_PARAMETERS: 258 return vpx_codec_control_(ctx, VP9E_SET_SVC_PARAMETERS, param); 259 default: 260 RTC_DCHECK_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; 261 } 262 return VPX_CODEC_ERROR; 263 } 264 265 vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, 266 vp8e_enc_control_id ctrl_id, 267 vpx_svc_frame_drop_t* param) const override { 268 switch (ctrl_id) { 269 case VP9E_SET_SVC_FRAME_DROP_LAYER: 270 return vpx_codec_control_(ctx, VP9E_SET_SVC_FRAME_DROP_LAYER, param); 271 default: 272 RTC_DCHECK_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; 273 } 274 return VPX_CODEC_ERROR; 275 } 276 277 vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, 278 vp8e_enc_control_id ctrl_id, 279 void* param) const override { 280 switch (ctrl_id) { 281 case VP9E_SET_SVC_PARAMETERS: 282 return vpx_codec_control_(ctx, VP9E_SET_SVC_PARAMETERS, param); 283 case VP9E_REGISTER_CX_CALLBACK: 284 return vpx_codec_control_(ctx, VP9E_REGISTER_CX_CALLBACK, param); 285 default: 286 RTC_DCHECK_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; 287 } 288 return VPX_CODEC_ERROR; 289 } 290 291 vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, 292 vp8e_enc_control_id ctrl_id, 293 vpx_svc_layer_id_t* param) const override { 294 switch (ctrl_id) { 295 case VP9E_SET_SVC_LAYER_ID: 296 return vpx_codec_control_(ctx, VP9E_SET_SVC_LAYER_ID, param); 297 case VP9E_GET_SVC_LAYER_ID: 298 return vpx_codec_control_(ctx, VP9E_GET_SVC_LAYER_ID, param); 299 default: 300 RTC_DCHECK_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; 301 } 302 return VPX_CODEC_ERROR; 303 } 304 305 vpx_codec_err_t codec_control( 306 vpx_codec_ctx_t* ctx, 307 vp8e_enc_control_id ctrl_id, 308 vpx_svc_ref_frame_config_t* param) const override { 309 switch (ctrl_id) { 310 case VP9E_SET_SVC_REF_FRAME_CONFIG: 311 return vpx_codec_control_(ctx, VP9E_SET_SVC_REF_FRAME_CONFIG, param); 312 case VP9E_GET_SVC_REF_FRAME_CONFIG: 313 return vpx_codec_control_(ctx, VP9E_GET_SVC_REF_FRAME_CONFIG, param); 314 default: 315 RTC_DCHECK_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; 316 } 317 return VPX_CODEC_ERROR; 318 } 319 320 vpx_codec_err_t codec_control( 321 vpx_codec_ctx_t* ctx, 322 vp8e_enc_control_id ctrl_id, 323 vpx_svc_spatial_layer_sync_t* param) const override { 324 switch (ctrl_id) { 325 case VP9E_SET_SVC_SPATIAL_LAYER_SYNC: 326 return vpx_codec_control_(ctx, VP9E_SET_SVC_SPATIAL_LAYER_SYNC, param); 327 default: 328 RTC_DCHECK_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; 329 } 330 return VPX_CODEC_ERROR; 331 } 332 333 vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, 334 vp8e_enc_control_id ctrl_id, 335 vpx_rc_funcs_t* param) const override { 336 switch (ctrl_id) { 337 case VP9E_SET_EXTERNAL_RATE_CONTROL: 338 return vpx_codec_control_(ctx, VP9E_SET_EXTERNAL_RATE_CONTROL, param); 339 default: 340 RTC_DCHECK_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; 341 } 342 return VPX_CODEC_ERROR; 343 } 344 345 vpx_codec_err_t codec_encode(vpx_codec_ctx_t* ctx, 346 const vpx_image_t* img, 347 vpx_codec_pts_t pts, 348 uint64_t duration, 349 vpx_enc_frame_flags_t flags, 350 uint64_t deadline) const override { 351 return ::vpx_codec_encode(ctx, img, pts, duration, flags, deadline); 352 } 353 354 const vpx_codec_cx_pkt_t* codec_get_cx_data( 355 vpx_codec_ctx_t* ctx, 356 vpx_codec_iter_t* iter) const override { 357 return ::vpx_codec_get_cx_data(ctx, iter); 358 } 359 360 const char* codec_error_detail(vpx_codec_ctx_t* ctx) const override { 361 return ::vpx_codec_error_detail(ctx); 362 } 363 364 const char* codec_error(vpx_codec_ctx_t* ctx) const override { 365 return ::vpx_codec_error(ctx); 366 } 367 368 const char* codec_err_to_string(vpx_codec_err_t err) const override { 369 return ::vpx_codec_err_to_string(err); 370 } 371 }; 372 373 } // namespace 374 375 std::unique_ptr<LibvpxInterface> LibvpxInterface::Create() { 376 return std::make_unique<LibvpxFacade>(); 377 } 378 379 } // namespace webrtc