summaryrefslogtreecommitdiffstats
path: root/third_party/aom/av1/encoder/global_motion.c
diff options
context:
space:
mode:
authorMatt A. Tobin <email@mattatobin.com>2020-04-07 23:30:51 -0400
committerwolfbeast <mcwerewolf@wolfbeast.com>2020-04-14 13:26:42 +0200
commit277f2116b6660e9bbe7f5d67524be57eceb49b8b (patch)
tree4595f7cc71418f71b9a97dfaeb03a30aa60f336a /third_party/aom/av1/encoder/global_motion.c
parentd270404436f6e84ffa3b92af537ac721bf10d66e (diff)
downloadUXP-277f2116b6660e9bbe7f5d67524be57eceb49b8b.tar
UXP-277f2116b6660e9bbe7f5d67524be57eceb49b8b.tar.gz
UXP-277f2116b6660e9bbe7f5d67524be57eceb49b8b.tar.lz
UXP-277f2116b6660e9bbe7f5d67524be57eceb49b8b.tar.xz
UXP-277f2116b6660e9bbe7f5d67524be57eceb49b8b.zip
Move aom source to a sub-directory under media/libaom
There is no damned reason to treat this differently than any other media lib given its license and there never was.
Diffstat (limited to 'third_party/aom/av1/encoder/global_motion.c')
-rw-r--r--third_party/aom/av1/encoder/global_motion.c298
1 files changed, 0 insertions, 298 deletions
diff --git a/third_party/aom/av1/encoder/global_motion.c b/third_party/aom/av1/encoder/global_motion.c
deleted file mode 100644
index e9f8b0bb4..000000000
--- a/third_party/aom/av1/encoder/global_motion.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (c) 2016, Alliance for Open Media. All rights reserved
- *
- * This source code is subject to the terms of the BSD 2 Clause License and
- * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
- * was not distributed with this source code in the LICENSE file, you can
- * obtain it at www.aomedia.org/license/software. If the Alliance for Open
- * Media Patent License 1.0 was not distributed with this source code in the
- * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <memory.h>
-#include <math.h>
-#include <assert.h>
-
-#include "av1/encoder/global_motion.h"
-
-#include "av1/common/warped_motion.h"
-
-#include "av1/encoder/segmentation.h"
-#include "av1/encoder/corner_detect.h"
-#include "av1/encoder/corner_match.h"
-#include "av1/encoder/ransac.h"
-
-#define MAX_CORNERS 4096
-#define MIN_INLIER_PROB 0.1
-
-#define MIN_TRANS_THRESH (1 * GM_TRANS_DECODE_FACTOR)
-
-// Border over which to compute the global motion
-#define ERRORADV_BORDER 0
-
-static const double erroradv_tr[] = { 0.65, 0.60, 0.55 };
-static const double erroradv_prod_tr[] = { 20000, 18000, 16000 };
-
-int is_enough_erroradvantage(double best_erroradvantage, int params_cost,
- int erroradv_type) {
- assert(erroradv_type < GM_ERRORADV_TR_TYPES);
- return best_erroradvantage < erroradv_tr[erroradv_type] &&
- best_erroradvantage * params_cost < erroradv_prod_tr[erroradv_type];
-}
-
-static void convert_to_params(const double *params, int32_t *model) {
- int i;
- int alpha_present = 0;
- model[0] = (int32_t)floor(params[0] * (1 << GM_TRANS_PREC_BITS) + 0.5);
- model[1] = (int32_t)floor(params[1] * (1 << GM_TRANS_PREC_BITS) + 0.5);
- model[0] = (int32_t)clamp(model[0], GM_TRANS_MIN, GM_TRANS_MAX) *
- GM_TRANS_DECODE_FACTOR;
- model[1] = (int32_t)clamp(model[1], GM_TRANS_MIN, GM_TRANS_MAX) *
- GM_TRANS_DECODE_FACTOR;
-
- for (i = 2; i < 6; ++i) {
- const int diag_value = ((i == 2 || i == 5) ? (1 << GM_ALPHA_PREC_BITS) : 0);
- model[i] = (int32_t)floor(params[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5);
- model[i] =
- (int32_t)clamp(model[i] - diag_value, GM_ALPHA_MIN, GM_ALPHA_MAX);
- alpha_present |= (model[i] != 0);
- model[i] = (model[i] + diag_value) * GM_ALPHA_DECODE_FACTOR;
- }
- for (; i < 8; ++i) {
- model[i] = (int32_t)floor(params[i] * (1 << GM_ROW3HOMO_PREC_BITS) + 0.5);
- model[i] = (int32_t)clamp(model[i], GM_ROW3HOMO_MIN, GM_ROW3HOMO_MAX) *
- GM_ROW3HOMO_DECODE_FACTOR;
- alpha_present |= (model[i] != 0);
- }
-
- if (!alpha_present) {
- if (abs(model[0]) < MIN_TRANS_THRESH && abs(model[1]) < MIN_TRANS_THRESH) {
- model[0] = 0;
- model[1] = 0;
- }
- }
-}
-
-void convert_model_to_params(const double *params, WarpedMotionParams *model) {
- convert_to_params(params, model->wmmat);
- model->wmtype = get_gmtype(model);
- model->invalid = 0;
-}
-
-// Adds some offset to a global motion parameter and handles
-// all of the necessary precision shifts, clamping, and
-// zero-centering.
-static int32_t add_param_offset(int param_index, int32_t param_value,
- int32_t offset) {
- const int scale_vals[3] = { GM_TRANS_PREC_DIFF, GM_ALPHA_PREC_DIFF,
- GM_ROW3HOMO_PREC_DIFF };
- const int clamp_vals[3] = { GM_TRANS_MAX, GM_ALPHA_MAX, GM_ROW3HOMO_MAX };
- // type of param: 0 - translation, 1 - affine, 2 - homography
- const int param_type = (param_index < 2 ? 0 : (param_index < 6 ? 1 : 2));
- const int is_one_centered = (param_index == 2 || param_index == 5);
-
- // Make parameter zero-centered and offset the shift that was done to make
- // it compatible with the warped model
- param_value = (param_value - (is_one_centered << WARPEDMODEL_PREC_BITS)) >>
- scale_vals[param_type];
- // Add desired offset to the rescaled/zero-centered parameter
- param_value += offset;
- // Clamp the parameter so it does not overflow the number of bits allotted
- // to it in the bitstream
- param_value = (int32_t)clamp(param_value, -clamp_vals[param_type],
- clamp_vals[param_type]);
- // Rescale the parameter to WARPEDMODEL_PRECISION_BITS so it is compatible
- // with the warped motion library
- param_value *= (1 << scale_vals[param_type]);
-
- // Undo the zero-centering step if necessary
- return param_value + (is_one_centered << WARPEDMODEL_PREC_BITS);
-}
-
-static void force_wmtype(WarpedMotionParams *wm, TransformationType wmtype) {
- switch (wmtype) {
- case IDENTITY:
- wm->wmmat[0] = 0;
- wm->wmmat[1] = 0;
- AOM_FALLTHROUGH_INTENDED;
- case TRANSLATION:
- wm->wmmat[2] = 1 << WARPEDMODEL_PREC_BITS;
- wm->wmmat[3] = 0;
- AOM_FALLTHROUGH_INTENDED;
- case ROTZOOM:
- wm->wmmat[4] = -wm->wmmat[3];
- wm->wmmat[5] = wm->wmmat[2];
- AOM_FALLTHROUGH_INTENDED;
- case AFFINE: wm->wmmat[6] = wm->wmmat[7] = 0; break;
- default: assert(0);
- }
- wm->wmtype = wmtype;
-}
-
-int64_t refine_integerized_param(WarpedMotionParams *wm,
- TransformationType wmtype, int use_hbd, int bd,
- uint8_t *ref, int r_width, int r_height,
- int r_stride, uint8_t *dst, int d_width,
- int d_height, int d_stride, int n_refinements,
- int64_t best_frame_error) {
- static const int max_trans_model_params[TRANS_TYPES] = { 0, 2, 4, 6 };
- const int border = ERRORADV_BORDER;
- int i = 0, p;
- int n_params = max_trans_model_params[wmtype];
- int32_t *param_mat = wm->wmmat;
- int64_t step_error, best_error;
- int32_t step;
- int32_t *param;
- int32_t curr_param;
- int32_t best_param;
-
- force_wmtype(wm, wmtype);
- best_error = av1_warp_error(wm, use_hbd, bd, ref, r_width, r_height, r_stride,
- dst + border * d_stride + border, border, border,
- d_width - 2 * border, d_height - 2 * border,
- d_stride, 0, 0, best_frame_error);
- best_error = AOMMIN(best_error, best_frame_error);
- step = 1 << (n_refinements - 1);
- for (i = 0; i < n_refinements; i++, step >>= 1) {
- for (p = 0; p < n_params; ++p) {
- int step_dir = 0;
- // Skip searches for parameters that are forced to be 0
- param = param_mat + p;
- curr_param = *param;
- best_param = curr_param;
- // look to the left
- *param = add_param_offset(p, curr_param, -step);
- step_error =
- av1_warp_error(wm, use_hbd, bd, ref, r_width, r_height, r_stride,
- dst + border * d_stride + border, border, border,
- d_width - 2 * border, d_height - 2 * border, d_stride,
- 0, 0, best_error);
- if (step_error < best_error) {
- best_error = step_error;
- best_param = *param;
- step_dir = -1;
- }
-
- // look to the right
- *param = add_param_offset(p, curr_param, step);
- step_error =
- av1_warp_error(wm, use_hbd, bd, ref, r_width, r_height, r_stride,
- dst + border * d_stride + border, border, border,
- d_width - 2 * border, d_height - 2 * border, d_stride,
- 0, 0, best_error);
- if (step_error < best_error) {
- best_error = step_error;
- best_param = *param;
- step_dir = 1;
- }
- *param = best_param;
-
- // look to the direction chosen above repeatedly until error increases
- // for the biggest step size
- while (step_dir) {
- *param = add_param_offset(p, best_param, step * step_dir);
- step_error =
- av1_warp_error(wm, use_hbd, bd, ref, r_width, r_height, r_stride,
- dst + border * d_stride + border, border, border,
- d_width - 2 * border, d_height - 2 * border,
- d_stride, 0, 0, best_error);
- if (step_error < best_error) {
- best_error = step_error;
- best_param = *param;
- } else {
- *param = best_param;
- step_dir = 0;
- }
- }
- }
- }
- force_wmtype(wm, wmtype);
- wm->wmtype = get_gmtype(wm);
- return best_error;
-}
-
-static INLINE RansacFunc get_ransac_type(TransformationType type) {
- switch (type) {
- case AFFINE: return ransac_affine;
- case ROTZOOM: return ransac_rotzoom;
- case TRANSLATION: return ransac_translation;
- default: assert(0); return NULL;
- }
-}
-
-static unsigned char *downconvert_frame(YV12_BUFFER_CONFIG *frm,
- int bit_depth) {
- int i, j;
- uint16_t *orig_buf = CONVERT_TO_SHORTPTR(frm->y_buffer);
- uint8_t *buf_8bit = frm->y_buffer_8bit;
- assert(buf_8bit);
- if (!frm->buf_8bit_valid) {
- for (i = 0; i < frm->y_height; ++i) {
- for (j = 0; j < frm->y_width; ++j) {
- buf_8bit[i * frm->y_stride + j] =
- orig_buf[i * frm->y_stride + j] >> (bit_depth - 8);
- }
- }
- frm->buf_8bit_valid = 1;
- }
- return buf_8bit;
-}
-
-int compute_global_motion_feature_based(TransformationType type,
- YV12_BUFFER_CONFIG *frm,
- YV12_BUFFER_CONFIG *ref, int bit_depth,
- int *num_inliers_by_motion,
- double *params_by_motion,
- int num_motions) {
- int i;
- int num_frm_corners, num_ref_corners;
- int num_correspondences;
- int *correspondences;
- int frm_corners[2 * MAX_CORNERS], ref_corners[2 * MAX_CORNERS];
- unsigned char *frm_buffer = frm->y_buffer;
- unsigned char *ref_buffer = ref->y_buffer;
- RansacFunc ransac = get_ransac_type(type);
-
- if (frm->flags & YV12_FLAG_HIGHBITDEPTH) {
- // The frame buffer is 16-bit, so we need to convert to 8 bits for the
- // following code. We cache the result until the frame is released.
- frm_buffer = downconvert_frame(frm, bit_depth);
- }
- if (ref->flags & YV12_FLAG_HIGHBITDEPTH) {
- ref_buffer = downconvert_frame(ref, bit_depth);
- }
-
- // compute interest points in images using FAST features
- num_frm_corners = fast_corner_detect(frm_buffer, frm->y_width, frm->y_height,
- frm->y_stride, frm_corners, MAX_CORNERS);
- num_ref_corners = fast_corner_detect(ref_buffer, ref->y_width, ref->y_height,
- ref->y_stride, ref_corners, MAX_CORNERS);
-
- // find correspondences between the two images
- correspondences =
- (int *)malloc(num_frm_corners * 4 * sizeof(*correspondences));
- num_correspondences = determine_correspondence(
- frm_buffer, (int *)frm_corners, num_frm_corners, ref_buffer,
- (int *)ref_corners, num_ref_corners, frm->y_width, frm->y_height,
- frm->y_stride, ref->y_stride, correspondences);
-
- ransac(correspondences, num_correspondences, num_inliers_by_motion,
- params_by_motion, num_motions);
-
- free(correspondences);
-
- // Set num_inliers = 0 for motions with too few inliers so they are ignored.
- for (i = 0; i < num_motions; ++i) {
- if (num_inliers_by_motion[i] < MIN_INLIER_PROB * num_correspondences) {
- num_inliers_by_motion[i] = 0;
- }
- }
-
- // Return true if any one of the motions has inliers.
- for (i = 0; i < num_motions; ++i) {
- if (num_inliers_by_motion[i] > 0) return 1;
- }
- return 0;
-}